Spring Security :: Oauth JWT(3)

hyunjoon park·2024년 2월 16일
1

Spring Security

목록 보기
11/12

Spring Boot + Security로 Oauth 공부하기 (with JWT)
https://www.youtube.com/watch?v=xsmKOo-sJ3c&list=PLJkjrxxiBSFALedMwcqDw_BPaJ3qqbWeB
개발자 유미님 유튜브를 보고 공부한 내용을 정리한다

구글 로그인 Client정보

Oauth Session 블로그에서 사용했던 구글 콘솔 api 설정 그대로 사용하겠다


application.yml & application.properties

spring:
  jpa:
    hibernate:
      ddl-auto: update
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: ${DB_URL}
    username: ${DB_USERNAME}
    password: ${DB_PASSWORD}

  main:
    allow-bean-definition-overriding: true
spring.security.oauth2.client.registration.google.client-id=${GOOGLE_CLIENT_ID}
spring.security.oauth2.client.registration.google.client-secret=${GOOGLE_CLIENT_SECRET}
spring.security.oauth2.client.registration.google.authorization-grant-type=authorization_code
spring.security.oauth2.client.registration.google.client-name=google
spring.security.oauth2.client.registration.google.redirect-uri=http://localhost:8080/login/oauth2/code/google
spring.security.oauth2.client.registration.google.scope=profile, email

SecurityConfig

package spring.oauth.jwt.global.config.security;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.Customizer;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.web.SecurityFilterChain;

@Configuration
@EnableWebSecurity
public class SecurityConfig {
  @Bean
  public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
    http
      .csrf(AbstractHttpConfigurer::disable)
      .cors(Customizer.withDefaults())
      .formLogin(AbstractHttpConfigurer::disable)
      .httpBasic(AbstractHttpConfigurer::disable)
      .oauth2Login(Customizer.withDefaults())
      .authorizeHttpRequests(
        (auth) -> auth
        .requestMatchers("/").permitAll()
        .anyRequest().authenticated()
      )
      .sessionManagement(
        (session) -> session
        .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
      );

    return http.build();
  }
}

CustomOAuth2UserService

package spring.oauth.jwt.domain.auth.service;

import org.springframework.security.oauth2.client.userinfo.DefaultOAuth2UserService;
import org.springframework.security.oauth2.client.userinfo.OAuth2UserRequest;
import org.springframework.security.oauth2.core.OAuth2AuthenticationException;
import org.springframework.security.oauth2.core.user.OAuth2User;
import org.springframework.stereotype.Service;

@Service
public class CustomOAuth2UserService extends DefaultOAuth2UserService {
  @Override
  public OAuth2User loadUser(OAuth2UserRequest userRequest) throws OAuth2AuthenticationException {
    OAuth2User oAuth2User = super.loadUser(userRequest);
    System.out.println("oAuth2User = " + oAuth2User);

    String registrationId = userRequest.getClientRegistration().getRegistrationId();

    if (registrationId.equals("google")) {

    }

    return null;
  }
}

OAuth2ResponseDto

package spring.oauth.jwt.domain.auth.presentation.dto;

public interface OAuth2Response {
  String getProvider();
  String getProviderId();
  String getEmail();
  String getName();
}

GoogleResponseDto

package spring.oauth.jwt.domain.auth.presentation.dto.google;

import spring.oauth.jwt.domain.auth.presentation.dto.OAuth2Response;

import java.util.Map;

public class GoogleResponse implements OAuth2Response {
  private final Map<String, Object> attribute;

  public GoogleResponse(Map<String, Object> attribute) {
    this.attribute = attribute;
  }

  @Override
  public String getProvider() {
    return "google";
  }

  @Override
  public String getProviderId() {
    return attribute.get("sub").toString();
  }

  @Override
  public String getEmail() {
    return attribute.get("email").toString();
  }

  @Override
  public String getName() {
    return attribute.get("name").toString();
  }
}

이 블로그랑 구현이 같다

CustomOAuth2UserService에 적용하기

package spring.oauth.jwt.domain.auth.service;

import org.springframework.security.oauth2.client.userinfo.DefaultOAuth2UserService;
import org.springframework.security.oauth2.client.userinfo.OAuth2UserRequest;
import org.springframework.security.oauth2.core.OAuth2AuthenticationException;
import org.springframework.security.oauth2.core.user.OAuth2User;
import org.springframework.stereotype.Service;
import spring.oauth.jwt.domain.auth.presentation.dto.OAuth2Response;
import spring.oauth.jwt.domain.auth.presentation.dto.google.GoogleResponse;

@Service
public class CustomOAuth2UserService extends DefaultOAuth2UserService {
  @Override
  public OAuth2User loadUser(OAuth2UserRequest userRequest) throws OAuth2AuthenticationException {
    OAuth2User oAuth2User = super.loadUser(userRequest);
    System.out.println("oAuth2User = " + oAuth2User);

    String registrationId = userRequest.getClientRegistration().getRegistrationId();

    OAuth2Response oAuth2Response = null;
    if (registrationId.equals("google")) {
      oAuth2Response = new GoogleResponse(oAuth2User.getAttributes());
    }

    return null;
  }
}

SecurityConfig 에 CustomOAuth2UserService 등록

package spring.oauth.jwt.global.config.security;

import lombok.RequiredArgsConstructor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.Customizer;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.web.SecurityFilterChain;
import spring.oauth.jwt.domain.auth.service.CustomOAuth2UserService;

@Configuration
@EnableWebSecurity
@RequiredArgsConstructor
public class SecurityConfig {
  private final CustomOAuth2UserService oAuth2UserService;
  @Bean
  public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
    http
      .csrf(AbstractHttpConfigurer::disable)
      .cors(Customizer.withDefaults())
      .formLogin(AbstractHttpConfigurer::disable)
      .httpBasic(AbstractHttpConfigurer::disable)
      // CustomOAuth2UserSerivce 등록
      .oauth2Login(oAuth2 -> oAuth2.userInfoEndpoint(
        userInfoEndpointConfig ->
          userInfoEndpointConfig.userService(oAuth2UserService))
      )
      .authorizeHttpRequests(
        (auth) -> auth
        .requestMatchers("/").permitAll()
        .anyRequest().authenticated()
      )
      .sessionManagement(
        (session) -> session
        .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
      );

    return http.build();
  }
}
profile
Backend Developer

0개의 댓글