스프링

WebSecurityConfigurerAdapter의 configure() 오버라이딩

nan2 2022. 1. 27. 16:38
반응형

WebSecurityConfigurerAdapter 를 extends 하는 클래스를 생성하면, configure() 오버라이딩 된다.

 

이때, configure()의 파라미터에 따라 3가지 메서드를 오버라이딩 할 수 있다.

 

1. void configure(HttpSecurity http) : 요청 경로에 대한 접근 권한, 로그인, 로그아웃 등 설정

 

2. void configure(WebSecurity web) : 특정한 요청을 무시할 수 있다.

 

3. void configure(AuthenticationManagerBuilder auth) : 사용자 인증 정보를 구성한다. 

 

(1) inmemory 방법

@Configuration
@EnableWebSecurity
@RequiredArgsConstructor
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        PasswordEncoder encoder = PasswordEncoderFactories.createDelegatingPasswordEncoder();
        auth.inMemoryAuthentication()
                .withUser("spring").password(encoder.encode("secret")).roles("USER");
    }
}

 

(2) jdbc 방법

@Configuration
@EnableWebSecurity
@RequiredArgsConstructor
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
    private final DataSource dataSource;

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.jdbcAuthentication()
            .dataSource(dataSource)
            // 패스워드 암호화
            .passwordEncoder(passwordEncoder())
            // 사용자 계정 확인하는 쿼리
            .userByUsernameQuery("select username, password from user where username = ? ")
            // 사용자 권한 확인하는 쿼리
            .authoritiesByUsernameQuery("select u.username, r.role 
                                         from user_role ur 
                                         inner join user u on ur.user_id = u.id
                                         inner join role r on ur.role_id = r.id 
                                         where u.username = ? ");
    }
}

(3) ldap 방법

 

(4) custom 방법

UserDetails 를 implements 하는 PrincipalDetails 클래스를 생성하고 findByUsername(String username) 함수를 이용함

@Data
public class PrincipalDetails implements UserDetails{
    private final BoardMember member;
    private Map<String,Object> attributes;

    @Autowired
    public PrincipalDetails(BoardMember member) {
        this.member = member;
    }

    @Override
    public Map<String, Object> getAttributes() {
        return attributes;
    }

    @Override
    public Collection<? extends GrantedAuthority> getAuthorities() {
        Collection<GrantedAuthority> collect = new ArrayList<>();
        collect.add(new GrantedAuthority() {
            @Override
            public String getAuthority() {
                return member.getRole();
            }
        });
        return collect;
    }

    @Override
    public String getPassword() {
        return member.getPassword();
    }

    @Override
    public String getUsername() {
        return member.getUsername();
    }

    @Override
    public boolean isAccountNonExpired() {
        return true;
    }

    @Override
    public boolean isAccountNonLocked() {
        return true;
    }

    @Override
    public boolean isCredentialsNonExpired() {
        return true;
    }

    @Override
    public boolean isEnabled() {
        return true;
    }

    @Override
    public String getName() {
        return null;
    }
}
@Service
@RequiredArgsConstructor
public class PrincipalDetailsService implements UserDetailsService {
    // Mapper에 username으로 User를 찾는 함수를 정의해준다.
    private final BoardMemberMapper boardMemberMapper;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        BoardMember findMember = boardMemberMapper.findByUsername(username);

        if(findMember == null){
        	// User가 존재하지 않으면 UsernameNotFoundException() 에러 발생
            throw new UsernameNotFoundException(username);
        }
	
    	// User가 존재하면 PrincipalDetail 타입으로 반환
        return new PrincipalDetails(findMember);
    }
}

 

@Configuration
@EnableWebSecurity
@RequiredArgsConstructor
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
    private final PrincipalDetailsService principalDetailsService;

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(principalDetailsService);
    }
}
반응형