해당 글은 Spring 작동원리에 대한 개인적인 예상을 작성 해놓은 글 입니다.
구글 Oauth2.0의 과정의 위의 이미지와 같이 일어난다.
여기서 access_token 으로 유저정보를 받아온 뒤의 과정을 설명하겠다.
@Slf4j
@Service
public class CustomOAuth2UserService implements OAuth2UserService<OAuth2UserRequest, OAuth2User> {
@Override
public OAuth2User loadUser(OAuth2UserRequest userRequest) throws OAuth2AuthenticationException {
OAuth2UserService<OAuth2UserRequest, OAuth2User> oAuth2UserService = new DefaultOAuth2UserService();
OAuth2User oAuth2User = oAuth2UserService.loadUser(userRequest);
String registrationId = userRequest.getClientRegistration().getRegistrationId();
String userNameAttributeName = userRequest.getClientRegistration()
.getProviderDetails().getUserInfoEndpoint().getUserNameAttributeName();
OAuth2Attribute oAuth2Attribute =
OAuth2Attribute.of(registrationId, userNameAttributeName, oAuth2User.getAttributes());
log.info("{}", oAuth2Attribute);
var memberAttribute = oAuth2Attribute.convertToMap();
// OAuth2User 를 상속받은 클래스
return new DefaultOAuth2User(
Collections.singleton(new SimpleGrantedAuthority("ROLE_USER")),
memberAttribute, "email");
}
}
유저정보를 받아온 뒤, OAuth2UserService의 loadUser 메서드가 호출된다. 해당 메서드는 OAuth2User 타입을 반환하는데, 반환된 OAuth2User로 SecurityContextHolder 에 Authentication 정보를 저장한다.
@Slf4j
@RequiredArgsConstructor
@Component
public class OAuth2SuccessHandler implements AuthenticationSuccessHandler {
private final TokenService tokenService;
private final UserRequestMapper userRequestMapper;
private final ObjectMapper objectMapper;
@Override
public void onAuthenticationSuccess(
HttpServletRequest request,
HttpServletResponse response,
Authentication authentication) throws IOException, ServletException {
OAuth2User oAuth2User = (OAuth2User)authentication.getPrincipal();
UserDto userDto = userRequestMapper.toDto(oAuth2User);
// 최초 로그인이라면 회원가입 처리를 한다.
Token token = tokenService.generateToken(userDto.getEmail(), "USER");
log.info("{}", token);
writeTokenResponse(response, token);
}
private void writeTokenResponse(HttpServletResponse response, Token token)
throws IOException {
response.setContentType("text/html;charset=UTF-8");
response.addHeader("Auth", token.getToken());
response.addHeader("Refresh", token.getRefreshToken());
response.setContentType("application/json;charset=UTF-8");
var writer = response.getWriter();
writer.println(objectMapper.writeValueAsString(token));
writer.flush();
}
}
만약 JWT 방식을 사용하려 한다면, loadUser 메서드에서 회원가입 관련 로직을 처리하고
토큰 관련 로직들은 loadUser 호출뒤에 내부적으로 호출되는 AuthenticationSuccessHandler 의 onAuthenticationSuccess 메서드를 오버라이딩하여 토큰 관련 로직들을 처리하면되고, 회원가입 관련 로직을 여기서 처리해도 된다.
@RequiredArgsConstructor
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
private final CustomOAuth2UserService oAuth2UserService;
private final OAuth2SuccessHandler successHandler;
private final TokenService tokenService;
@Override
protected void configure(HttpSecurity http) throws Exception {
http.httpBasic().disable()
.csrf().disable()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.authorizeRequests()
.antMatchers("/token/**").permitAll()
.antMatchers("/login").permitAll()
.anyRequest().authenticated()
.and()
.oauth2Login()
.successHandler(successHandler)
.userInfoEndpoint().userService(oAuth2UserService);
http.addFilterBefore(new JwtAuthFilter(tokenService),
UsernamePasswordAuthenticationFilter.class);
}
}
참조 : https://zkdlu.tistory.com/12
'Server > 작동 원리 예상' 카테고리의 다른 글
[Spring] Spring Security 동작 과정. (0) | 2022.08.07 |
---|---|
Spring에서 요청이 들어왔을 때 동작 과정 (0) | 2022.08.02 |
[Spring] Session 이용한 로그인 후 인가 과정 (0) | 2022.08.02 |