application.properties
#registration
spring.security.oauth2.client.registration.서비스명.client-name=서비스명
spring.security.oauth2.client.registration.서비스명.client-id=서비스에서 발급 받은 아이디
spring.security.oauth2.client.registration.서비스명.client-secret=서비스에서 발급 받은 비밀번호
spring.security.oauth2.client.registration.서비스명.redirect-uri=서비스에 등록한 우리쪽 로그인 성공 URI
spring.security.oauth2.client.registration.서비스명.authorization-grant-type=authorization_code
spring.security.oauth2.client.registration.서비스명.scope=리소스 서버에서 가져올 데이터 범위
#provider
spring.security.oauth2.client.provider.서비스명.authorization-uri=서비스 로그인 창 주소
spring.security.oauth2.client.provider.서비스명.token-uri=토큰 발급 서버 주소
spring.security.oauth2.client.provider.서비스명.user-info-uri=사용자 정보 획득 주소
spring.security.oauth2.client.provider.서비스명.user-name-attribute=응답 데이터 변수
예시
#Naver
#registration
spring.security.oauth2.client.registration.naver.client-name=naver
spring.security.oauth2.client.registration.naver.client-id=${NAVER_CLIENT_ID}
spring.security.oauth2.client.registration.naver.client-secret=${NAVER_CLIENT_KEY}
spring.security.oauth2.client.registration.naver.redirect-uri=http://localhost:8080/login/oauth2/code/naver
spring.security.oauth2.client.registration.naver.authorization-grant-type=authorization_code
spring.security.oauth2.client.registration.naver.scope=name,email
#provider
spring.security.oauth2.client.provider.naver.authorization-uri=https://nid.naver.com/oauth2.0/authorize
spring.security.oauth2.client.provider.naver.token-uri=https://nid.naver.com/oauth2.0/token
spring.security.oauth2.client.provider.naver.user-info-uri=https://openapi.naver.com/v1/nid/me
spring.security.oauth2.client.provider.naver.user-name-attribute=response
#Google
#registration
spring.security.oauth2.client.registration.google.client-name=google
spring.security.oauth2.client.registration.google.client-id=${GOOGLE_CLIENT_ID}
spring.security.oauth2.client.registration.google.client-secret=${GOOGLE_CLIENT_KEY}
spring.security.oauth2.client.registration.google.redirect-uri=http://localhost:8080/login/oauth2/code/google
spring.security.oauth2.client.registration.google.authorization-grant-type=authorization_code
spring.security.oauth2.client.registration.google.scope=name,email
#Kakao
#registration
spring.security.oauth2.client.registration.kakao.client-name=kakao
spring.security.oauth2.client.registration.kakao.client-id=${KAKAO_CLIENT_ID}
spring.security.oauth2.client.registration.kakao.client-secret=${KAKAO_CLIENT_KEY}
spring.security.oauth2.client.registration.kakao.redirect-uri=http://localhost:8080/login/oauth2/code/kakao
spring.security.oauth2.client.registration.kakao.authorization-grant-type=authorization_code
spring.security.oauth2.client.registration.kakao.scope=profile_nickname
spring.security.oauth2.client.registration.kakao.client-authentication-method=POST
#provider
spring.security.oauth2.client.provider.kakao.authorization-uri=https://kauth.kakao.com/oauth/authorize
spring.security.oauth2.client.provider.kakao.token-uri=https://kauth.kakao.com/oauth/token
spring.security.oauth2.client.provider.kakao.user-info-uri=https://kapi.kakao.com/v2/user/me
spring.security.oauth2.client.provider.kakao.user-name-attribute=id
SecurityConfig.java
@Configuration
@EnableWebSecurity
public class SecurityConfig {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
//csrf disable
http
.csrf((auth) -> auth.disable());
//From 로그인 방식 disable
http
.formLogin((auth) -> auth.disable());
//HTTP Basic 인증 방식 disable
http
.httpBasic((auth) -> auth.disable());
//oauth2
http
.oauth2Login(Customizer.withDefaults());
//경로별 인가 작업
http
.authorizeHttpRequests((auth) -> auth
.requestMatchers("/").permitAll()
.anyRequest().authenticated());
//세션 설정 : STATELESS
http
.sessionManagement((session) -> session
.sessionCreationPolicy(SessionCreationPolicy.STATELESS));
return http.build();
}
}
(작성 예정)
구글 로그인
CustomOAuth2UserService.java
@Service
@RequiredArgsConstructor
public class CustomOAuth2UserService extends DefaultOAuth2UserService {
private final UserRepository userRepository;
@Override
public OAuth2User loadUser(OAuth2UserRequest userRequest) throws OAuth2AuthenticationException {
OAuth2User oAuth2User = super.loadUser(userRequest);
System.out.println(oAuth2User);
String registrationId = userRequest.getClientRegistration().getRegistrationId();
OAuth2Response oAuth2Response;
switch (registrationId) {
case "naver" -> oAuth2Response = new NaverResponse(oAuth2User.getAttributes());
case "google" -> oAuth2Response = new GoogleResponse(oAuth2User.getAttributes());
default -> {
return null;
}
}
String username = oAuth2Response.getProvider() + " " + oAuth2Response.getProviderId();
User existData = userRepository.findByUsername(username);
if (existData == null) {
User user = new User();
user.setUsername(username);
user.setEmail(oAuth2Response.getEmail());
user.setName(oAuth2Response.getName());
user.setRole("ROLE_USER");
userRepository.save(user);
UserDto userDto = new UserDto();
userDto.setUsername(username);
userDto.setName(oAuth2Response.getName());
userDto.setRole("ROLE_USER");
return new CustomOAuth2User(userDto);
} else {
existData.setEmail(oAuth2Response.getEmail());
existData.setName(oAuth2Response.getName());
userRepository.save(existData);
UserDto userDto = new UserDto();
userDto.setUsername(existData.getUsername());
userDto.setName(oAuth2Response.getName());
userDto.setRole(existData.getRole());
return new CustomOAuth2User(userDto);
}
}
}
SecurityConfig.java
@Configuration
@EnableWebSecurity
@RequiredArgsConstructor
public class SecurityConfig {
private final CustomOAuth2UserService customOAuth2UserService;
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
...
//oauth2
http
.oauth2Login((oauth2) -> oauth2
.userInfoEndpoint(
(userInfoEndpointConfig -> userInfoEndpointConfig.userService(customOAuth2UserService))));
...
}
}
OAuth 로그인 방식으로 CustomOAuth2UserService 등록 (리소스 서버에서 유저 정보를 넘겨주는 부분)
CustomSuccessHandler.java
@Component
@RequiredArgsConstructor
public class CustomSuccessHandler extends SimpleUrlAuthenticationSuccessHandler {
private final JWTUtil jwtUtil;
@Override
public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,
Authentication authentication) throws IOException, ServletException {
//OAuth2User
CustomOAuth2User customUserDetails = (CustomOAuth2User) authentication.getPrincipal();
String username = customUserDetails.getUsername();
Collection<? extends GrantedAuthority> authorities = authentication.getAuthorities();
Iterator<? extends GrantedAuthority> iterator = authorities.iterator();
GrantedAuthority auth = iterator.next();
String role = auth.getAuthority();
String token = jwtUtil.createJwt(username, role, 60 * 60 * 60L);
response.addCookie(createCookie("Authorization", "Bearer " + token));
response.sendRedirect("http://localhost:3000/");
}
private Cookie createCookie(String key, String value) {
Cookie cookie = new Cookie(key, value);
cookie.setMaxAge(60 * 60 * 60);
//cookie.setSecure(true);
cookie.setPath("/");
cookie.setHttpOnly(true);
return cookie;
}
}
OAuth2 로그인이 성공했을 때, JWT토큰을 발급할 클래스
SecurityConfig.java
@Configuration
@EnableWebSecurity
@RequiredArgsConstructor
public class SecurityConfig {
...
private final CustomSuccessHandler customSuccessHandler;
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
...
//oauth2
http
.oauth2Login((oauth2) -> oauth2
.userInfoEndpoint(
(userInfoEndpointConfig -> userInfoEndpointConfig.userService(customOAuth2UserService)))
.successHandler(customSuccessHandler)
);
...
}
}
의존성 및 successHandler 추가
나머지 JWTFilter 부분은 JWT 구현 방식과 동일
'Web > Spring Security' 카테고리의 다른 글
Spring Security 6.x.x CORS 설정 (0) | 2025.02.27 |
---|---|
JWT 방식 OAuth2.0 클라이언트 동작 원리 (0) | 2025.02.26 |
Spring Security 6.x.x JWT 보안 요소 추가 (0) | 2025.02.20 |
Spring Security 6.x.x JWT 기반 인증 인가 (0) | 2025.02.15 |
Spring Security JWT 인증 인가 순서 (0) | 2025.02.14 |