본문 바로가기

[SPRING]/Security

Spring Security5 OAuth2

반응형
  1. Spring Security 5 OAuth
  2. Spring Security 5 이전의 OAuth
  3. OAuth Client 설정 및 주의할 점
  4. OAuth Server 설정 및 주의할 점

Spring Security란?

  • Spring Framework 기반 인증, 인가 프레임워크
  • Spring 기반 애플리케이션에서는 사실상 표준(de-facto standard)

Spring Security 5

  • Spring Boot 2.0부터 이용가능
  • Spring Framework 5.0 기반
  • 새로운 특징
    • OAuth 2.0 Login

Spring Security 5 OAuth

아래와 같이 이용

@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter{
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.oauth2Login()
            .clientRegistrationRepository(clientRegistrationRepository())
            .authorizedClientService(authorizedClientService());
    }
}

Spring Security 5 이전의 OAuth

Spring Security 4까지 – Spring Security OAuth

  • Spring Security OAuth라는 별도 모듈로 존재했음.

    • org.springframework.security.oauth:spring-security-oauth
    • org.springframework.security.oauth:spring-security-oauth2
  • OAuth 1.0, OAuth 2.0 지원

  • OAuth Client, Resource Source, Authorization Server 지원

  • Spring Security OAuth 불편한점

    • 기존의 form login이나 지금의 oauth login과는 코딩 스타일이 다르고 확장 포인트가 불명확함
    • OAuth Login 기능을 명시적으로 제공하지 않음
    • OAuth 로그인을 하려면 먼저 로그인을 해야하는등...

Spring Security 5 릴리즈

  • 5.0 릴리즈(2018. 11.) – OAuth Client
  • 5.2 릴리즈(2019. 10.) – Resource Server

Authorization Server는 다른 프로젝트로 지원

  • (0.2.0)Spring Authorization Server GA 릴리즈 (2021.08.) - Authorization Server

Spring Security 5 Client 적용하기

  1. application.properties파일 설정

유명한 OAuth2 Provider의 경우

  • Google
  • Github
  • Facebook
  • Okta

application.properties파일

spring.security.oauth2.client.registration.github.client-id=…
spring.security.oauth2.client.registration.github.client-secret=…

으로 쉽게 이용 가능

유명한 OAuth2 Provider가 아닌 경우

application.properties파일

spring.security.oauth2.client.registration.authclient.provider=authserv
spring.security.oauth2.client.registration.authclient.client-id=…
spring.security.oauth2.client.registration.authclient.client-secret=...
spring.security.oauth2.client.registration.authclient.authorization-grant-type=authorization_code
spring.security.oauth2.client.registration.authclient.redirect-uri=…

spring.security.oauth2.client.provider.authserv.authorization-uri=…
spring.security.oauth2.client.provider.authserv.token-uri=…
spring.security.oauth2.client.provider.authserv.user-info-uri=…
spring.security.oauth2.client.provider.authserv.user-name-attribute=username

주의할 점

OAuth2AuthorizedClientService Bean 기본 구현이 in memory 임

  1. SecruityConfig 파일 설정
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.oauth2Login()
            .clientRegistrationRepository(clientRegistrationRepository())
            .authorizedClientService(authorizedClientService());
    }
}

ClientRegistration의 경우 인메모리 방식을 이용해도 큰 문제가 없을 것이다.
그러나 authorizedClientService는 jdbc 템플릿 혹은 앱내에서 이용하는 db엑세스 기술(mybatis, jpa 등....)을 이용하는것을 추천한다.

@Bean
public ClientRegistrationRepository clientRegistrationRepository() {
    return new InMemoryClientRegistrationRepository(ClientRegistration.withRegistrationId("payco")
                                                                        .clientId("...")
                                                                        .clientSecret("...")
                                                                        // ...
                                                                        .build());
}
@Bean
public OAuth2AuthorizedClientService authorizedClientService() {
    return new JdbcOAuth2AuthorizedClientService(jdbcTemplate, clientRegistrationRepository());
}
.oauth2Login()
    .clientRegistrationRepository(clientRegistrationRepository())
    .authorizedClientService(authorizedClientService())
    .authorizationEndpoint()
        .authorizationRequestResolver(authorizationRequestResolver())
        .and()
    .redirectionEndpoint()
        .baseUri("/login/oauth2/callback/*")
        .and()
    .userInfoEndpoint()
        .userService(oauth2UserService())
        .customUserType(PaycoOAuth2User.class, "payco")
        .and()

Spring Security 5 Server 적용하기

  1. pom.xml
<dependency>
    <groupId>org.springframework.security</groupId>
    <artifactId>spring-security-oauth2-authorization-server</artifactId>
    <version>0.3.0</version>
</dependency>
  1. Authorization Server Config
@Configuration(proxyBeanMethods = false)  //이 설정이 다른 bean에 주입되지 않도록 설정
public class AuthorizationServerConfig {
    @Bean
    @Order(Ordered.HIGHEST_PRECEDENCE) //설정시 우선순위 높게 설정
    public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
        OAuth2AuthorizationServerConfiguration.applyDefaultSecurity(http);
        return http.formLogin(Customizer.withDefaults()).build();
    }
    @Bean
    public RegisteredClientRepository registeredClientRepository() { // OAuth Client 등록 정보
        // ...
    }
    @Bean
    public JWKSource<SecurityContext> jwkSource() { // JWS (JSON Web Key Set)
        return (jwkSelector, securityContext) -> jwkSelector.select(new JWKSet(Jwks.generateRsa()));
    }
    @Bean
    public ProviderSettings providerSettings() {. // Provider 설정 정보
        return ProviderSettings.builder().issuer("http://server.com:8080").build();
    }
}
  1. Default Web Security Config
@EnableWebSecurity
@Configuration
public class DefaultSecurityConfig {
    @Bean
    SecurityFilterChain defaultSecurityFilterChain(HttpSecurity http) throws Exception {
        return http.authorizeRequests(authorizeRequests
                                    -> authorizeRequests.anyRequest().authenticated())
                    .formLogin(Customizer.withDefaults())
                    .build();
    }
    @Bean
    UserDetailsService users() {
        // ...
    }
}

참고 : https://forward.nhn.com/2021/sessions/4

반응형