SMALL
UserDetailsService, AuthenticationProvider
UserDetailsService, AuthenticationProvider 이것들은 무엇일까? 아래의 사진을 보자.
위에 사진처럼 AuthenticationProvider 걸치고 UserDetailsService 에서 검사한 후 다시 AuthenticationProvider 에 걸쳐서 response 하게 된다. 이때 내가 원하는 방식되로 검사하고 권한설정을 하여 인증 단게를 할수 있다.
코드
@Service
@RequiredArgsConstructor
@Slf4j
public class LoginService implements UserDetailsService, AuthenticationProvider {
private final UserRepository repository;
private final PasswordEncoding passwordEncoding;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
Optional<User> optionalUser = repository.findByUserId(username);
if (optionalUser.isEmpty()) {
throw new UsernameNotFoundException("User not found with username: " + username);
}
User user = optionalUser.get();
return new UserDetail(user);
}
@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
UserDetails userDetail = loadUserByUsername(authentication.getName());
String password = authentication.getCredentials().toString();
if (!(passwordEncoding.getEncoding().matches(password, userDetail.getPassword()))) {
return null;
}
return new UsernamePasswordAuthenticationToken(userDetail, password, userDetail.getAuthorities());
}
@Override
public boolean supports(Class<?> authentication) {
return authentication.equals(UsernamePasswordAuthenticationToken.class);
}
}
위에 처럼 loadUserByUsername 에서 유저가 있는지 DB 를 통해 확인을 한뒤. authentication 에서 권한 단계를 걸쳐
다시한번 DB 에서 데이터를 가져와 내가 만든 UserDetails 로 가져와서 비밀번호를 비교한다. 가끔씩 생각하는건 구지
loadUserByUsername 매서드를 써야 할까? authenticate 매서드로만으로도 충분히 해결이 될텐데 생각이 들지만, 좀더 공부해봐야겠다...!
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http.
csrf(csrf -> csrf
.disable()
)
.authorizeHttpRequests(req -> req
.requestMatchers(
"/api/v1/register",
"/api/v1/email",
"/api/v1/email-success",
"/api/v1/login",
"/api/v1/forget",
"/api/forget/**"
).permitAll()
.anyRequest().authenticated()
)
.formLogin(login -> login
.loginProcessingUrl("/api/v1/login")
.usernameParameter("userid")
.passwordParameter("password")
.failureHandler(securityFailHandler)
.successHandler(successHandler)
)
.authenticationProvider(loginService)
;
return http.build();
}
조금더 설명을 더 붙이자면 formLogin 을 쓸려고 하면 무조건 Parameter 로 userid, password 를 받아야 한다.
바꾸고 싶었지만 그렇게 되면 Security를 쓸 필요가 없어지는것 같아 안쓰고 Security 에서 제공해주는 것으로 받아서 사용했다. 이때 로그인 실패 할때랑 성공할때를 Handler 를 만들어서 사용할수 있다.
실패 : AuthenticationFailureHandler 인터페이스 상속
성공 : AuthenticationSuccessHandler 인터페이스 상속
반응형
LIST
'Spring' 카테고리의 다른 글
@Component / @ComponentScan (0) | 2023.06.13 |
---|---|
Request 와 Response (4) | 2023.06.09 |
Json 방식으로 데이터 보내기 (0) | 2023.06.08 |
Validation 유효성 검증 (2) | 2023.06.02 |
Redis (2) (0) | 2023.06.01 |