본문 바로가기

카테고리 없음

[Java] spring boot에서 spring security 사용하기 4 - OAuth2

들어가기

OAuth(”Open Authorization”)은 애플리케이션 간에 인증을 공유하는 형태로 별도 인증을 통하여 애플리케이션에 대한 접근권한을 위임하는 개방형 표준이다. 트위터, 페이스북,구글,Github 등 유명 회사에서 제공하고 있다. OAuth에 장점은 별도 회원가입이나 인증 처리을 개발할 필요없고 여러 애플리케이션을 통합하는게 가능하다. 여기서는 OAuth 클라이언트 관점에서 접근하려고 한다.

작성자: http://ospace.tistory.com/ (ospace114@empal.com)

기본 구성

Dependency 설정

Pom.xml 파일에 OAuth2 인증을 위해 spring security 외에 추가적인 dependency가 필요하다.

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-oauth2-client</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.security</groupId>
    <artifactId>spring-security-oauth2-core</artifactId>
</dependency>

spring-security-oauth2-core은 나중에 나올 ClientRegistrationRepository을 이용한 설정에서 ClientAuthenticationMethod를 사용하기 위해서 추가했다.

HTML 파일

제대로 동작하는지 확인하기 위한 index.html 파일을 추가하자.

“/resources/static/index.html” 파일을 생성한다.

<html lang="en">
<body>
    <h1>Hello world!</h1>
    <a href="/logout">Logout</a>
</body>
</html>

Spring Security 설정

OAuth 로그인을 사용하기 위해 간단하게 oauth2Login()으로 설정한다.

@Configuration
@EnableWebSecurity
public class SecurityConfig {
    @Bean
    SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http
                .authorizeHttpRequests(req->req
                        .anyRequest().fullyAuthenticated()
                )
                .oauth2Login(Customizer.withDefaults())

        return http.build();
    }
}

이제 OAuth2을 사용할 준비는 끝났다.

프로바이더 설정

application.properties에서 설정

Google을 사용하는 예를 보자. Google console로 가서 OAuth을 설정해주면 된다. 먼저 “OAuth 동의 화면”에서 OAuth을 설정해주고 “사용자 인증 정보” 화면에서 “사용자 인증 정보 만들기”를 통해서 OAuth 클라이언트 ID를 생성하면 된다. 그러면 글라이언트 ID와 시큐리티 ID를 얻을 수 있다.

CommonOAuth2Provider에서 Google, GitHub, Facebook, Okta 같은 유명한 provider인 경우는 기본 클라이언트 속성을 사전에 정의되었기 때문에 설정할 부분이 많지 않지만, 사용자 정의 provider인 경우는 설정할 때 확인해야할 부분 조금 많다.

Spring boot 2.x에서 제공하는 ClientRegistration 속성 매핑 정보이다.

  • spring.security.oauth2.client.registration.[registrationId]
    • provider
    • client-id
    • client-secret
    • client-authentication-method
    • authorization-grant-type
    • redirect-uri
    • scope
    • client-name
  • spring.security.oauth2.client.provider.[registrationId]
    • authorization-uri
    • token-uri
    • jwk-set-uri
    • issuer-uri
    • user-info-uri
    • user-info-authentication-method
    • user-name-attribute

registrationId로 인증 프로바이더를 식별한다. 만약 예를 들어 google을 google-login으로 다른 이름을 사용할 경우에도 provider 속성으로 사용할 인증 프로바이더를 선택할 수 있다.

application.properties 파일에 얻은 값을 설정해주면 된다.

spring.security.oauth2.client.registration.google.client-id=google-client-id
spring.security.oauth2.client.registration.google.client-secret=google-client-secret

google-client-id 대신에 획득한 클라이언트 ID로 google-client-secret 대신에 획득한 시큐리티 ID를 입력하면 된다. 물론 이외에 다른 속성도 변경할 수 있다. 물론 꼭 필요한 경우가 아니라면 할 필요는 없다.

http://localhost:8080/login” 링크로 접속하면 아래와 같은 화면이 보인다.

Google을 클릭하면 익숙한 접근 허용 페이지가 보이고 허용하면 정상적으로 페이지가 보인다. 앞으로는 허용 페이지는 보이지 않고 로그인하면 바로 접속된다.

Spring Security 설정에서 사용자 정의

설정 파일을 사용하지 않고 ClientRegistrationRepository 빈객체를 만들어서 속성을 설정할 수 있다. 단, 사전 정의 값은 사용할 수 없어서 모두 설정해줘야 한다.

@Configuration
public class OAuth2LoginConfig {

    @Bean
    public ClientRegistrationRepository clientRegistrationRepository() {
        return new InMemoryClientRegistrationRepository(this.googleClientRegistration());
    }

    private ClientRegistration googleClientRegistration() {
        return ClientRegistration.withRegistrationId("google")
            .clientId("google-client-id")
            .clientSecret("google-client-secret")
            .clientAuthenticationMethod(ClientAuthenticationMethod.CLIENT_SECRET_BASIC)
            .authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE)
            .redirectUri("{baseUrl}/login/oauth2/code/{registrationId}")
            .scope("openid", "profile", "email", "address", "phone")
            .authorizationUri("https://accounts.google.com/o/oauth2/v2/auth")
            .tokenUri("https://www.googleapis.com/oauth2/v4/token")
            .userInfoUri("https://www.googleapis.com/oauth2/v3/userinfo")
            .userNameAttributeName(IdTokenClaimNames.SUB)
            .jwkSetUri("https://www.googleapis.com/oauth2/v3/certs")
            .clientName("Google")
            .build();
    }
}

Github

프로젝트 경로: https://github.com/ospace/spring-works/tree/main/spring-security-04

결론

지금은 기본 환경에서 설정하는 방식을 살펴보았다. oauth2Login()에는 다양한 옵션을 지원한다. 좀더 깊게 들어갈려고 하는데 시간이 생각보다 많이 걸려서 기본적인 oauth을 설정하는 방법만 올렸다. properties에서 유명한 프로바이더인 경우는 기본설정이 되어 있기 때문에 간단하지만 그외에 프로바이터인 경우는 일일히 설정해줘야 한다. 해당 프로바이더에서 OAuth 관련 문서를 참고하면 크게? 어렵지는 않다. ㅡ.ㅡ;;;

물론 가급적 설정 파일로 분리하는게 추후 운영에 좀더 좋을 수 있다. 물론 다른 방식으로 설정내용을 관리하는 방안도 있을 수 있다.

부족한 글이지만 여러분에게 도움이 되었으면 하네요. 모두 즐거운 코딩생활 되세요. ^^ ospace.

참고

[1] OAuth2 Log In - Core Configuration, https://docs.spring.io/spring-security/reference/servlet/oauth2/login/core.html

반응형