Spring Boot OAuth2 인증서버 적용기 - 1

황남욱·2021년 12월 14일
0
post-thumbnail

저는 회사에서 프로젝트를 진행하면서 통합회원연동을 맡아 클라이언트단을 작업했었는데 그때 통합회원 서버쪽에서 사용한 것이 OAuth2이고 인증 서버도 만들어 보면 좋겠다 라고 생각해서 만들게 되었습니다.

OAuth Authorization은 클라이언트가 서비스 제공자로부터 회원정보를 제공받기 위해 인증 및 권한을 부여받는 절차라고 생각하면 됩니다.

예를들면 카카오, 구글, 페이스북 등이 대표적인 서비스 제공자입니다.

authorization 서버의 인증 타입은 아래와 같이 4가지가 있습니다.
Authorization Code Grant Type,Implicit Grant Type, Resource Owner Password Credential Grant Type, Client Credential Grant Type

이 중 대중적으로 이용되는 Authorization Code Grant Type 을 사용하여 만들어 보도록 하겠습니다.

프로젝트 구성

  • Spring Boot
  • Gradle
  • H2
  • lombok
  • JPA

build.gradle 내용

plugins {
    id 'org.springframework.boot' version '2.6.1'
    id 'io.spring.dependency-management' version '1.0.11.RELEASE'
    id 'java'
    id 'war'
}

group = 'com.mycloset'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '11'

configurations {
    compileOnly {
        extendsFrom annotationProcessor
    }
}

repositories {
    mavenCentral()
}

dependencies {
    implementation 'org.springframework.security:spring-security-jwt'
    implementation 'org.springframework.boot:spring-boot-starter-data-redis'
    implementation 'org.springframework.boot:spring-boot-starter-oauth2-client'
    implementation 'org.springframework.boot:spring-boot-starter-oauth2-resource-server'
    implementation group: 'org.springframework.security.oauth', name: 'spring-security-oauth2', version: '2.3.5.RELEASE'
    implementation 'org.springframework.security.oauth.boot:spring-security-oauth2-autoconfigure:2.5.2'
    implementation 'org.springframework.boot:spring-boot-starter-data-rest'
    implementation 'org.springframework.boot:spring-boot-starter-security'
    implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
    implementation 'com.google.code.gson:gson'
    compileOnly 'org.projectlombok:lombok'
    runtimeOnly 'com.h2database:h2'
    annotationProcessor('org.projectlombok:lombok')
    testImplementation 'org.springframework.boot:spring-boot-starter-test'
    testImplementation 'org.springframework.security:spring-security-test'
}

test {
    useJUnitPlatform()
}

Authorization Server Config


@Configuration
@EnableAuthorizationServer
public class OAuth2AuthorizationConfig extends AuthorizationServerConfigurerAdapter {

    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception{
       clients.inMemory()
                .withClient("foo")
                .secret("bar")
                .redirectUris("http://localhost:1995/oauth2/callback")
                .authorizedGrantTypes("authorization_code")
                .scopes("read", "write")
                .accessTokenValiditySeconds(30000);
    }
}

@Configuration
@EnableAuthorizationServer
어노테이션을 사용하여 인증서버를 활성화 시킵니다.

인증이 완료되면 redirectUris에 명시된 Url로 Code값을 실어서 보내줍니다.

Security Config


@EnableWebSecurity
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Bean
    public PasswordEncoder passwordEncoder() {
        return NoOpPasswordEncoder.getInstance();
    }
    
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.inMemoryAuthentication()
                .withUser("user")
                .password("{noop}pass")
                .roles("USER");
    }
    
    @Override
    protected void configure(HttpSecurity http) throws Exception {

        http.csrf().disable()
                .headers().frameOptions().disable()
                .and()
                .authorizeRequests()
                .antMatchers(
                        "/oauth/**",
                        "/oauth2/callback",
                        "/h2/**"
                ).permitAll()
                .and()
                .formLogin().and()
                .httpBasic();
    }
}

아직 로그인 폼이 준비되어있지 않으므로 시큐리티 기본 로그인 폼을 사용합니다.

PasswordEncoder

추후엔 암호화를 하여 저장하지만 현재는 암호화준비가 아직 안되었으므로 NoOpPasswordEncoder를 사용합니다.

더미 회원정보 셋팅

Security버전이 높아지면서 PasswordEncoder 사용시 발생되는 에러를 막기위해 {noop}를 앞에 추가해줍니다.

Security Configure

csrf 는 사용안함 처리
headers().frameOptions().disable() 은 시큐리티 사용시 H2콘솔에 접근이 막히므로 세팅합니다.

oauth/** , /oauth2/callback, /h2/**
이 3개는 인증없이 접근 가능하도록 변경합니다.

application.properties

server.port=1995

spring.h2.console.enabled=true
spring.h2.console.path=/h2

#DB
spring.datasource.driver-class-name=org.h2.Driver
spring.datasource.url=jdbc:h2:mem:oauth;MODE=MySQL;
spring.datasource.username=sa
spring.datasource.password=
spring.datasource.initialization-mode=always
spring.datasource.schema=classpath:h2/schema.sql
spring.datasource.data=classpath:h2/data.sql

#JPA
spring.jpa.database-platform=org.hibernate.dialect.H2Dialect
spring.jpa.hibernate.ddl-auto=update
spring.jpa.properties.hibernate.show_sql=true
spring.jpa.properties.hibernate.format_sql=true
logging.level.org.hibernate.SQL=debug
logging.level.org.hibernate.type=trace

H2, JPA 설정이 담겨있습니다.

profile
안녕하세요👋 주니어 백엔드 개발자입니다.

0개의 댓글