뭐라도 끄적이는 BLOG

Spring Security OAuth(Google) 본문

SpringFramework/Spring Security

Spring Security OAuth(Google)

Drawhale 2023. 7. 9. 10:34

OAuth

Google, Facebook과 같은 다양한 플랫폼의 특정 사용자 데이터에 접근하기 위해 제3자 클라이언트가 사용자의 접근 권한을 위임받을 수 있는 표준 프로토콜이다. 우리 서비스가 다른 클라이언트에게 접근 권한을 위임해 줄 수도 있다.

Spring OAuth Client

Spring Security에서 기본적으로 Google, Github, Facebook 3가지 OAuth사용방법을 만들어 놓았다. 이외 OAuth Client는 사용자가 Custom으로 생성해 주어야 한다. 이번에는 기본적으로 제공해 주는 Google, Github, Facebook만 사용해 본다.

implementation 'org.springframework.boot:spring-boot-starter-oauth2-client'

oauth2 client의존성을 추가한다.

@Configuration
@EnableWebSecurity
public class SecurityConfiguration {
    @Bean
    SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http
                .authorizeHttpRequests(authorize -> {
                    authorize.requestMatchers(HttpMethod.GET, "/").permitAll();
                    authorize.requestMatchers(HttpMethod.GET, "/user/**").hasRole("USER");
                    authorize.requestMatchers(HttpMethod.GET, "/admin/**").hasRole("ADMIN");
                    authorize.anyRequest().authenticated();
                })
                .csrf(AbstractHttpConfigurer::disable)
                .headers(header-> header.frameOptions(HeadersConfigurer.FrameOptionsConfig::disable))
                .formLogin(withDefaults())
                .httpBasic(withDefaults())
                .oauth2Login(withDefaults());
        return http.build();
    }
    @Bean
    JdbcUserDetailsManager jdbcUserDetailsManager(DataSource dataSource) {
        return new JdbcUserDetailsManager(dataSource);
    }

    @Bean
    DataSource dataSource() {
        return DataSourceBuilder.create()
                .driverClassName("org.h2.Driver")
                .url("jdbc:h2:mem:testdb")
                .username("sa")
                .password("")
                .build();
    }
}

그리고 위와 같은 Configuration을 설정한다. 이전 포스팅에서부터 따라왔다면 .oauth2Login(withDefaults()); 만 추가되었다는 것을 확인할 수 있다.

spring:
  security:
    oauth2:
      client:
        registration:
          google:
            client-id: id
            client-secret: secret
          github:
            client-id: id
            client-secret: secret
          facebook:
            client-id: id
            client-secret: secret

이제 application.yml에 oauth2설정정보를 추가하면 된다.

각 플랫폼의 client-id와 client-secret을 추가할 때마다 아래 Login with Oauth 2.0의 목록이 추가되는 것을 확인할 수 있다. 각 목록을 클릭하면 각 플랫폼의 로그인 화면으로 갈 수 있으나 현재 client-id와 client-secret은 임의로 넣은 것이기 때문제 제대로 동작하지 않고 에러화면으로 전환된다.

Google OAuth

Google OAuth를 사용하는 방법을 살펴본다.

일단 GCP에 들어간뒤 아무 Project를 하나 생성한다. 이후 API 및 서비스 → 사용자인증 정보 → 사용자 인증정보 만들기에서 OAuth 2.0 클라이언트 ID를 생성할 수 있다.

생성하기 이전 OAuth 동의 화면을 먼저 만들라고 리다이렉션이 되는데 간단히 이름과 이메일만 적으면 되는 부분이라서 생략한다.

+사용자 인증 정보 만들기를 클릭하면 OAuth 클라이언트 ID가 나오는데 이를 선택한다.

OAuth 클라이언트 ID만들기에서 유형을 웹 애플리케이션으로 선택하면 아래 입력 폼이 추가된다.

OAuth Client 이름과 승인된 리디렉션 URI에 http://localhost:8080/login/oauth2/code/google를 입력한 뒤 만들기 버튼을 클릭하자.

이후 처음 사용자 인증 정보 화면으로 되돌아가면서 위와같은 modal창이 나오고 Client-id와 Client-secret을 제공해 준다. client-secret은 해당 화면을 닫으면 다시 찾아볼 수 없으므로 JSON다운로드로 저장해 두거나 다른 곳에 기록해 두어야 한다.

spring:
  security:
    oauth2:
      client:
        registration:
          google:
            client-id: [client-id]
            client-secret: [client-secret]

이제 다시 Application으로 돌아와서 application.yml파일의 google.client-id와 google.client-secret에 정보를 입력해준다. 그리고 접근할 uri에 접근 권한을 하나 추가해줘야 하는데 그 내용은 아래와 같다.

참고로 client-id나 client-secret을 gcp에서 삭제했더라도 github에 해당 내용을 push하지말자. 보안경고 이메일이 계속 온다...
authorize.requestMatchers(HttpMethod.GET, "/user/**").hasAnyAuthority("ROLE_USER", "OIDC_USER");

OIDC_USER라는 접근 ROLE을 하나 추가해 주었다. 이제 애플리케이션을 실행후 /user에 접근하면 로그인 화면이 나오고 아래 Login with OAuth 2.0에서 Google을 클릭하면 Google Login이 진행된다. Google Login을 완료하면 우리 애플리케이션으로 돌아오고 /user에 접근할 수 있는 모습을 볼 수 있다.

로그인한 뒤 /user화면이다 화면에 Google Login ID와 Login 한 User의 Authorities를 보여줄 수 있도록 만들었다.

반응형