스프링시큐리티인액션 12장. oauth2
oauth2 구성요소
OAuth란 Open Authorization의 약자
1.사용자 : 사용자 이름과 암호로 신원 증명 / 리소스 서버가 노출하는 리소스를 소유하는 개인
2.클라이언트 : 사용자를 대신해 사용자가 소유한 리소스에 접근하는 애플리케이션. 클라이언트는 클라이언트 id와 클라이언트 비밀을 이용해 신원을 증명.
클라이언트는 요청할 때 자신을 증명하는 자체 자격 증명이 필요.
3.리소스서버 : 사용자가 소유한 리소스를 호스팅하는 서버. 리소스는 사용자의 데이터이거나 사용자가 수행할 수 있는 작업
4.권한부여서버 : 리소스 서버가 노출하는 사용자의 리소스에 접근할 권한을 부여하는 애플리케이션. 권한부여서버는 클라이언트가 사용자 대신 리소스에 접근 권한이 있다고 결정하면 토큰을 발급한다. 클라이언트는 이 토큰을 이용해 권한 부여서버에서 권한을 받았음을 리소스 서버에 증명.


구분 | 설명 |
Resource Owner | 웹 서비스를 이용하려는 유저, 자원(개인정보)을 소유하는 자, 사용자 'Resource' 는 개인정보라고 생각하면 된다. |
Client | 자사 또는 개인이 만든 애플리케이션 서버 클라이언트 라는 이름은 client가 Resource server에게 필요한 자원을 요청하고 응답하는 관계여서 그렇다. |
Authorization Server | 권한을 부여(인증에 사용할 아이템을 제공주는)해주는 서버다. 사용자는 이 서버로 ID, PW를 넘겨 Authorization Code를 발급 받을 수 있다. Client는 이 서버로 Authorization Code을 넘겨 Token을 받급 받을 수 있다. |
Resource Server | 사용자의 개인정보를 가지고있는 애플리케이션 (Google, Facebook, Kakao 등) 회사 서버 Client는 Token을 이 서버로 넘겨 개인정보를 응답 받을 수 있다. |
그랜트? 애플리케이션이 액세스 토큰을 얻기 위해 사용할 수 있는
다양한 흐름을 그랜트라고 한다. 시스템 아키텍처에 따라 적합한 그랜트 유형을 선택해야 한다.
승인코드 그랜트 유형은 사용자가 직접 권한 부여 서버에서 인증하여
클라이언트가 액세스 토큰을 얻을 수 있게 해준다. 이 그랜트 유형은
사용자가 클라이언트를 신뢰하지 않고 클라이언트와 자격증명을 공유하기를 원하지 않을 때 적합 - 인증 요청시 새창이 떠서 구글이나 네이버로 들어가서 자격증명 할 경우
암호 그랜트 유형 - 사용자가 자신의 자격증명을 클라이언트와 공유한다고 가정. 클라이언트를 신뢰할 수 있는 경우에만 이 유형을 적용.
클라이언트 자격 증명 그랜트 유형 - 클라이언트가 자격 증명으로만 인증하여 토큰을 얻는다는 의미이다. 클라이언트가 사용자의 리소스가 아닌 리소스 서버의 엔드포인트를 호출해야 할 때 이 그랜트 유형을 선택한다.
pom.xml에 디펜던시 추가
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-oauth2-client</artifactId>
</dependency>

소스 코드 중 핵심은 이 부분
클라이언트 id와 시크릿값은 깃허브에서 위와 같이 추가할 수 있고
package com.laurentiuspilca.ssia.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.oauth2.client.CommonOAuth2Provider;
import org.springframework.security.oauth2.client.registration.ClientRegistration;
import org.springframework.security.oauth2.client.registration.ClientRegistrationRepository;
import org.springframework.security.oauth2.client.registration.InMemoryClientRegistrationRepository;
import org.springframework.security.oauth2.core.AuthorizationGrantType;
@Configuration
public class ProjectConfig extends WebSecurityConfigurerAdapter {
@Bean
public ClientRegistrationRepository clientRepository() {
var c = clientRegistration();
return new InMemoryClientRegistrationRepository(c);
}
private ClientRegistration clientRegistration() {
return CommonOAuth2Provider.GITHUB.getBuilder("github")
.clientId("123")
.clientSecret("123")
.build();
}
// private ClientRegistration clientRegistration() {
// ClientRegistration cr = ClientRegistration.withRegistrationId("github")
// .clientId("a7553955a0c534ec5e6b")
// .clientSecret("1795b30b425ebb79e424afa51913f1c724da0dbb")
// .scope(new String[]{"read:user"})
// .authorizationUri("https://github.com/login/oauth/authorize")
// .tokenUri("https://github.com/login/oauth/access_token")
// .userInfoUri("https://api.github.com/user")
// .userNameAttributeName("id")
// .clientName("GitHub")
// .authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE)
// .redirectUriTemplate("{baseUrl}/{action}/oauth2/code/{registrationId}")
// .build();
// return cr;
// }
@Override
protected void configure(HttpSecurity http) throws Exception {
http.oauth2Login();
http.authorizeRequests()
.anyRequest().authenticated();
}
}
configure메소드에서 http.oauth2login을 통해 github와 연동이 됨
스프링 시큐리티는 clientregistration의 인스턴스를 이용해 권한 부여서버에서 클라이언트의 등록을 나타냄.
스프링시큐리티 oauth2 구현에서 특정 클라이언트 등록을 찾는 책임이 있는 구성요소를 clientregistration repository
스프링시큐리티로 oauth2 클라이언트를 구현할 때는 사용 가능한 clientregistration이 하나 이상 있는 clientregistrationrepository객체를 정의
간단히 설명해서 oauth2를 쓰기 위해서 configuration 부분에서 클라이언트 레지스트레이션과 리파지토리를 구현해줘야 쓸 수 있음.
그리고 localhost로 요청을 하면
내가 만든 spring security in action이 있는 깃허브에서 권한을 부여해주는 것을 보여줄 수 있음.
정상적으로 부여되면 hello there가 보임.
