04 JDBC 기반 인증

11166 단어 springSecurity
앞의 장의 데 이 터 는 완전히 데이터베이스 에서 나 온 것 이 아 닙 니 다. 예 를 들 어 spring security 사용 자 는 처음에 xml 설정 만 했 을 뿐 나중에 데이터 베이스 로 바 뀌 었 습 니 다. 또한 권한 은 도구 류 에 따라 가상 되 었 습 니 다. 다음 의 예 는 계속 개선 하 겠 습 니 다. 본 고 는 chapter 04.00 - calendar 를 바탕 으로 수정 되 었 습 니 다.
1. 그룹 기반 접근 제어 JdbcUserDetailsManager 는 사용자 와 Granted Authority 의 성명 사이 의 간접 층 을 추가 하고 그룹 을 나 누 어 Granted Authority 를 그룹 이 라 고 부 르 는 논리 집합 으로 만 드 는 것 을 지원 합 니 다.그 다음 에 사용 자 는 하나 이상 의 그룹 으로 배정 되 었 습 니 다. 그 구성원 이 한 그룹의 Granted Authority 성명 1. 데이터 원본 을 설정 하고 데 이 터 를 초기 화 합 니 다. 표 정의 와 초기 화 합 니 다.
a.security-schema.sql
create table users(
    username varchar(256) not null primary key,
    password varchar(256) not null,
    enabled boolean not null
);

create table authorities (
    username varchar(256) not null,
    authority varchar(256) not null,
    constraint fk_authorities_users foreign key(username) references users(username)
);
create unique index ix_auth_username on authorities (username,authority);
b.security-users.sql
insert into users (username,password,enabled) values ('[email protected]','user1',1);
insert into users (username,password,enabled) values ('[email protected]','admin1',1);
insert into users (username,password,enabled) values ('[email protected]','admin1',1);
insert into users (username,password,enabled) values ('[email protected]','disabled1',0);
c.security-groups-schema.sql
create table groups (
    id bigint generated by default as identity(start with 0) primary key,
    group_name varchar(256) not null
);

create table group_authorities (
    group_id bigint not null,
    authority varchar(50) not null,
    constraint fk_group_authorities_group foreign key(group_id) references groups(id)
);

create table group_members (
    id bigint generated by default as identity(start with 0) primary key,
    username varchar(50) not null,
    group_id bigint not null,
    constraint fk_group_members_group foreign key(group_id) references groups(id)
);
d.security-groups-mappings.sql
-----
-- Create the Groups
insert into groups(group_name) values ('Users');
insert into groups(group_name) values ('Administrators');

-----
-- Map the Groups to Roles
insert into group_authorities(group_id, authority) select id,'ROLE_USER' from groups where group_name='Users';
-- Administrators are both a ROLE_USER and ROLE_ADMIN
insert into group_authorities(group_id, authority) select id,'ROLE_USER' from groups where group_name='Administrators';
insert into group_authorities(group_id, authority) select id,'ROLE_ADMIN' from groups where group_name='Administrators';

-----
-- Map the users to Groups
insert into group_members(group_id, username) select id,'[email protected]' from groups where group_name='Users';
insert into group_members(group_id, username) select id,'[email protected]' from groups where group_name='Administrators';
insert into group_members(group_id, username) select id,'[email protected]' from groups where group_name='Users';
insert into group_members(group_id, username) select id,'[email protected]' from groups where group_name='Users';
service.xml
<jdbc:embedded-database id="dataSource" type="H2">
        <jdbc:script location="classpath:/database/h2/calendar-schema.sql"/>
        <jdbc:script location="classpath:/database/h2/calendar-data.sql"/>
        <jdbc:script location="classpath:/database/h2/security-schema.sql"/>
        <jdbc:script location="classpath:/database/h2/security-users.sql"/>
        <jdbc:script location="classpath:/database/h2/security-groups-schema.sql"/>
        <jdbc:script location="classpath:/database/h2/security-groups-mappings.sql"/>
    </jdbc:embedded-database>
2. JdbcUserDetailsManager 사용 그룹 설정
기본적으로 Spring Security 는 GBAC 를 사용 하지 않 았 습 니 다.따라서 Spring security 사용 팀 의 사용 을 지적 해 야 합 니 다.
security. xml 파일 을 수정 할 때 group - authorities - by - username - query 를 사용 합 니 다. 다음 과 같 습 니 다.
<authentication-manager>
  <authentication-provider>
	<jdbc-user-service id="userDetailsService" data-source-ref="dataSource"
	 group-authorities-by-username-query=
		"select
		g.id, g.group_name, ga.authority
		from
		groups g, group_members gm, group_authorities ga
		where
		gm.username = ? and g.id = ga.group_id and g.id = gm.group_id"/>
  </authentication-provider>
</authentication-manager>

3. 가입 시 호출
userDetailsManager.createUser(userDetails);

Security Context 호출 설정
UserDetails userDetails = userDetailsService.loadUserByUsername(user.getEmail());
        UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(userDetails,
                user.getPassword(),userDetails.getAuthorities());
        SecurityContextHolder.getContext().setAuthentication(authentication);

4. 제 티 테스트 시작
2. 사용자 정의 방안 을 지원 합 니 다. 많은 데이터 베 이 스 는 spring security 의 데이터 시트 정의 에 부합 되 지 않 지만 JdbcDaoImpl 로 매 핑 합 니 다. JdbcUserDetails Manager 는 세 가지 명확 한 정의 매개 변수 와 열 을 되 돌려 주 는 sql 조회 가 있 습 니 다. 네 임 스페이스 조회 의 속성 이름 설명 은 SQL 열 users - by - username - query: 사용자 이름과 일치 하 는 사용 자 를 되 돌려 줍 니 다.그러나 첫 번 째 사용자 만 사 용 됩 니 다. Username (string), Password (string), Enabled (Boolean) authorities - by - username - query: 사용자 에 게 직접 부여 하 는 권한 을 하나 이상 되 돌려 줍 니 다.일반적으로 GBAC 가 비활성 화 된 경우 에 사 용 됩 니 다. Username (string), Granted Authority (string) group - authorities - by - username - query: 그룹 구성원 관 계 를 통 해 사용자 의 권한 과 그룹 정 보 를 되 돌려 줍 니 다. GBAC 를 사용 할 때 사용 합 니 다. Group Primary Key (any), Group Name (any), Granted Authority (string) 반환 열 은 JdbcUserDetails Manager 의 기본 값 을 사용 하지 않 아 도 됩 니 다.그러나 이 열 들 은 어떻게 든 되 돌아 가 야 합 니 다. 1. 다시 이전 예 로 돌아 가면 보안 으로 시작 하 는 sql 을 모두 옮 기 고 calendar - authorities. sql 을 추가 합 니 다. 다음 과 같 습 니 다.
<jdbc:embedded-database id="dataSource" type="H2">
	<jdbc:script location="classpath:/database/h2/calendar-schema.sql"/>
	<jdbc:script location="classpath:/database/h2/calendar-data.sql"/>
	<jdbc:script location="classpath:/database/h2/calendar-authorities.sql"/>
</jdbc:embedded-database>
2.DefaultCalendarService.java
    private final JdbcOperations jdbcOperations;
    @Autowired
    public DefaultCalendarService(EventDao eventDao, CalendarUserDao userDao, JdbcOperations jdbcOperations) {
    ...
    this.jdbcOperations = jdbcOperations;
    }

    public int createUser(CalendarUser user) {
        int userId = userDao.createUser(user);
        jdbcOperations.update("insert into calendar_user_authorities(calendar_user,authority) values (?,?)",
        userId, "ROLE_USER");
        return userId;
    }
3. JdbcUserDetailsManager 를 설정 하여 사용자 정의 sql 조 회 를 사용 합 니 다.
        <authentication-provider>
            <jdbc-user-service id="userDetailsService" data-source-ref="dataSource"
                users-by-username-query="select email,password,true
                from calendar_users
                where email = ?"
                authorities-by-username-query="select cua.id, cua.authority
                from calendar_users cu, calendar_user_authorities cua
                where cu.email = ? and  cu.id = cua.calendar_user"/>
        </authentication-provider>
4. 제 티 테스트 시작
3. 보안 암 호 를 설정 합 니 다. 암호 화 된 암호 가 더 안전 하 다 는 것 을 알 고 있 습 니 다. spring security 는 많은 인 코더 들 을 실현 해 주 었 습 니 다. 모두 o. s. authentication. encoding 패키지 아래 에 두 었 습 니 다. 1. 인 코더 bean 을 설명 합 니 다.
<bean:bean id="passwordEncoder"
       xmlns="http://www.springframework.org/schema/beans"
       class="org.springframework.security.authentication.encoding.ShaPasswordEncoder">
	<constructor-arg value="256"/>
</bean:bean>
2. spring security 에 passwordEncoder 를 알 게 합 니 다. < authentication - provider > 의 하위 요소 에 < password - encoder ref = "passwordEncoder" / > 를 추가 합 니 다.
3. 이 두 단계 가 있 습 니 다. 만약 에 앞의 응용 프로그램 을 사용 하면 한 사용 자 를 등록 하면 자동 으로 로그 인 할 수 있 지만 h2 데이터 베 이 스 를 찾 아 보 니 비밀번호 가 바 뀌 지 않 았 고 예전 의 사용자 도 로그 인 할 수 없 었 습 니 다.
현재 새로 등 록 된 사용 자 를 종료 하 는 것 처럼 로그 인 할 수 없습니다. 이 유 는 간단 합 니 다. 제 가 저장 하지 않 았 을 때 사용자 의 비밀 번 호 는 암호 인 코더 인 코딩 을 거치 지 않 았 습 니 다. 그래서 업데이트 하 겠 습 니 다.
Default CalendarService, passwordEncoder 를 주입 합 니 다. (이 책 을 발견 한 저 자 는 구조 기 방법 으로 bean 을 주입 하 는 것 을 좋아 합 니 다) 그리고 createuser 방법 으로 user. setPassword (passwordEncoder. encodePassword (user. getPassword (), null) 를 사용 합 니 다.그리고 새로 등 록 된 사용 자 를 발견 하면 로그 인 할 수 있 습 니 다. 물론 초기 화 된 사용자 update 는 인 코딩 된 비밀번호 와 마찬가지 로 로그 인 할 수 있 습 니 다.
4. 비밀 번 호 를 위해 소금 을 더 넣 습 니 다. 앞의 예 는 사용자 의 비밀번호 가 같 으 면 최종 적 으로 데이터베이스 에 저 장 된 암호 데이터 도 마찬가지 입 니 다. 다른 데 이 터 를 저장 할 수 있다 면 더욱 안전 합 니 다. 명문 비밀 번 호 를 적당 한 소금 과 함께 암호 화하 여 생 성 한 밀 문 은 다 를 수 있 습 니 다. 일반적인 소금 은 두 가지 가 있 습 니 다. a. 사용자 와 관련 된 데 이 터 를 알고리즘 에 따라 생 성 합 니 다.사용자 가 만 든 시간 과 같이;b. 무 작위 로 생 성 되 고 사용자 의 비밀번호 와 함께 특정한 형식 으로 저장 합 니 다. 소금 이 명문 암호 에 들 어 갔 기 때문에 단 방향 암호 화 를 사용 할 수 없습니다. 지정 한 사용자 에 게 는적절 한 소금 값 을 얻어 비밀 번 호 를 계산 해 야 하 는 하 쉬 를 사용자 가 저장 한 하 쉬 와 비교 하여 인증 을 완료 합 니 다. spring security 는 소금, spring security 3.1 의 spring - security - core 와 spring - security - crypto 를 사용 하여 o. s. crypto. password. Password Encoder 를 우선 사용 하 는 방법 을 제공 합 니 다.무 작위 소금 을 사 용 했 기 때 문 입 니 다. 이 인 터 페 이 스 는 o. s. crypto. bcrypt. BCryptPasswordEncoder: 검색 공격 을 방지 합 니 다.o. s. crypto. password. NoOpPasswordEncoder: 암호 o. s. crypto. password. StandardPasswordEncoder 를 명문 으로 되 돌려 줍 니 다. SHA - 256 여러 번 교체 하고 무 작위 소금 값 을 사용 합 니 다. passwordEncoder 는 다음 과 같 습 니 다. < bean: bean id = "passwordEncoder" class = "org. springframework. security. crypto. password. StandardPasswordEncoder"/ > 2. password - encoder 는 변 하지 않 는 3. DefaultCalendarService 에 있 는 passwordEncoder 를 인용 하여 o. s. crypto. password. PasswordEncoder 형식 을 주입 합 니 다. 이전의 o. s. authentication. encoding. PasswordEncoder 가 아 닙 니 다.createUser 방법 호출 user. setPassword (passwordEncoder. encode (user. getPassword ())) 사용 하기;4. Jetty 테스트 를 다시 시작 한 다음 에 이 예 가 비밀번호 와 인증 을 어떻게 저장 하 는 지 봅 니 다. a. 비밀 번 호 를 저장 합 니 다. 먼저 무 작위 소금 과 원본 비밀 번 호 를 해시 에 저장 한 다음 에 소금 과 해시 를 조합 하여 salt = randomsalt () hash = hash (salt + original Password) stored Password = salt + hash b. 인증: 비밀 번 호 를 저장 하여 소금 과 해시 (단 방향 암호 화 할 수 없습니다) 를 얻 습 니 다.. 그리고 입력 한 비밀번호 와 소금 을 해시 로 진행 합 니 다. 이 두 해시 가 같 으 면 인증 을 통과 합 니 다. stored Password = datasource. lookupPassword (username) salt, expected Hash = extractSalt AndHash (stored Password) actual Hash = hash (salt + input Password) authenticated = (expected Hash = = actual Hash)

좋은 웹페이지 즐겨찾기