SpringSecurityConfig 파일
@Configuration
@RequiredArgsConstructor
@EnableWebSecurity
public class SpringSecurityConfig {
private final MemberService memberService;
private final PasswordEncoder bCryptPasswordEncoder;
private final CustomJwtProvider customJwtProvider;
private final AuthenticationConfiguration authenticationConfiguration;
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.httpBasic().disable()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS) //JWT토큰 사용하므로 세션사용 X
.and()
.csrf(csrf -> csrf.disable())
.cors(cors -> cors.disable())
.headers(headers -> headers.frameOptions().disable())
.authorizeHttpRequests(authorize -> authorize
.requestMatchers(new AntPathRequestMatcher("/lib/admin/**")).hasAnyAuthority(Role.ADMIN.getRoleValue()) //인가권한이 ADMIN인 경우만 가능
.requestMatchers(new AntPathRequestMatcher("/lib/member/signup")).permitAll() //회원가입 요청은 익명 사용자 가능
.requestMatchers(new AntPathRequestMatcher("/lib/member/**")).hasAnyAuthority(Role.MEMBER.getRoleValue()) //그 외 기능은 인간권한 MEMBER인 경우만 가능
.anyRequest().authenticated() //어떠한 요청이든 인증 필요
)
.authenticationProvider(authenticationProvider()) //커스터마이징한 provider세팅
.addFilterBefore(new JwtAuthenticationFilter(authenticationManager(), customJwtProvider), UsernamePasswordAuthenticationFilter.class)
.addFilterBefore(new JwtAuthorizationFilter(authenticationManager(), customJwtProvider, memberService), BasicAuthenticationFilter.class)
.formLogin(login -> login.disable())
.exceptionHandling(authenticationManger -> authenticationManger
.authenticationEntryPoint(new CustomAuthenticationEntryPoint()) //인증Exception 처리
.accessDeniedHandler(new CustomAccessDeniedHandler()) //AccessDeniedException 처리
)
;
return http.build();
}
@Bean
public AuthenticationProvider authenticationProvider(){
return new CustomAuthenticationProvider(memberService,bCryptPasswordEncoder);
}
@Bean
public AuthenticationManager authenticationManager() throws Exception { //AuthenticationManager Bean등록
return this.authenticationConfiguration.getAuthenticationManager();
}
}
AuthenticationProvider 구현체
@Slf4j
@Component
@RequiredArgsConstructor
public class CustomAuthenticationProvider implements AuthenticationProvider {
private final MemberService memberService;
private final PasswordEncoder bCryptPasswordEncoder;
@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
log.info("CustomAuthenticationProvider.authenticate start");
String id = authentication.getPrincipal().toString();
String pwd = authentication.getCredentials().toString();
UserDetails ud= memberService.loadUserByUsername(id);
//비밀번호 일치 여부 확인
checkPassword(pwd,ud.getPassword());
Collection<? extends GrantedAuthority> authorities = ud.getAuthorities();
return new UsernamePasswordAuthenticationToken(ud,pwd,authorities);
}
@Override
public boolean supports(Class<?> authentication) {
return true;
}
private void checkPassword(String inputPwd, String dbPwd){
if ( !bCryptPasswordEncoder.matches(inputPwd,dbPwd) ){
throw new PassWordMisMatchException(RESULTCODE.RESULT_PASSWORDMISMATCH);
}
}
}
위와 같이 세팅하였으나 커스터마이징한 구현체의 메소드가 실행되지 않았다...
개선
AuthenticationProvider 구현체
@Slf4j
//@Component
@RequiredArgsConstructor
public class CustomAuthenticationProvider implements AuthenticationProvider {
private final MemberService memberService;
private final PasswordEncoder bCryptPasswordEncoder;
@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
log.info("CustomAuthenticationProvider.authenticate start");
String id = authentication.getPrincipal().toString();
String pwd = authentication.getCredentials().toString();
UserDetails ud= memberService.loadUserByUsername(id);
//비밀번호 일치 여부 확인
checkPassword(pwd,ud.getPassword());
Collection<? extends GrantedAuthority> authorities = ud.getAuthorities();
return new UsernamePasswordAuthenticationToken(ud,pwd,authorities);
}
@Override
public boolean supports(Class<?> authentication) {
return true;
}
private void checkPassword(String inputPwd, String dbPwd){
if ( !bCryptPasswordEncoder.matches(inputPwd,dbPwd) ){
throw new PassWordMisMatchException(RESULTCODE.RESULT_PASSWORDMISMATCH);
}
}
}
@Component 제거하니 구현체의 메소드들이 실행된다.
왜???
아직 못 찾음.. 일단 넘어가고 추후 확인해볼 예정
'SpringBoot > SpringSecurity' 카테고리의 다른 글
리소스 접근 시 인증,인가 Exception 처리 (0) | 2023.10.19 |
---|---|
JwtAuthenticationFilter 내 발생 가능한 Exception 공통 처리 (0) | 2023.10.19 |