OAuth2
OAuth2란?
특정 애플리케이션(Client)에서 사용자의 인증을 직접 처리하는 것이 아니라 사용자 정보를 보유하고 있는 신뢰할 만한
써드 파티 애플리케이션(GitHub, Google, Facebook 등)에서 사용자의 인증을 대신 처리해 주고 Resource에 대한 자격 증명용 토큰을 발급한 후,
Client가 해당 토큰을 이용해 써드 파티 애플리케이션의 서비스를 사용하게 해주는 방식입니다.
동작방식
Resource Owner는 Client 역할을 하는 웹 애플리케이션에게 OAuth2 인증을 요청합니다.
Resource Owner는 자신의 계정 정보를 관리하고 있는 써드 파티 애플리케이션에 로그인하길 원하는 것이며,
이 요청을 Client인 웹 애플리케이션에 전송하는 것입니다. (로그인화면 제공 X)
Client는 R Resource Owner의 계정 정보를 관리하고 있는 써드 파티 애플리케이션에 로그인할 수 있도록
써드 파티 애플리케이션의 로그인 페이지로 리다이렉트(Redirect)합니다.
로그인 인증을 진행하고 로그인 인증에 성공하면,
Authorization Server가 Resource Owner의 로그인 인증이 성공적으로 수행되었음을 증명하는 Access Token을 Client에게 전송합니다.
Client는 이제 Resource Owner의 대리인 역할을 수행할 수 있게 되었으므로, Resource Server에게 Resource Owner 소유의 Resource를 요청
Resource Server는 Client가 전송한 Access Token을 검증해서 Resource Owner의 Resource를 Client에게 전송합니다.
어떤 Resource를 소유하고 있는 Resource Owner를 대신하는 Client가 Resource Owner의 대리인 역할을 수행한다는 것
OAuth2 구현
의존성 추가
1
2
3
implementation 'org.springframework.boot:spring-boot-starter-security'
implementation 'org.springframework.boot:spring-boot-starter-oauth2-client'
application.yml 클라이언트 정보 추가
1
2
3
4
5
6
7
8
9
security:
oauth2:
client:
registration:
google:
clientId: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
clientSecret: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Configuration을 통해 Bean을 등록해서 OAuth 2의 인증을 설정
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
@Configuration
public class SecurityConfiguration {
@Value("${spring.security.oauth2.client.registration.google.clientId}") // 구글 클라이언트 아이디
private String clientId;
@Value("${spring.security.oauth2.client.registration.google.clientSecret}") // 구글 클라이언트 비밀번호
private String clientSecret;
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.csrf().disable()
.formLogin().disable()
.httpBasic().disable()
.authorizeHttpRequests(authorize -> authorize
.anyRequest().authenticated()
)
.oauth2Login(withDefaults());
return http.build();
}
// // ClientRegistrationRepository 을 빈으로 등록
@Bean
public ClientRegistrationRepository clientRegistrationRepository() {
var clientRegistration = clientRegistration();
return new InMemoryClientRegistrationRepository(clientRegistration);
}
//
private ClientRegistration clientRegistration() {
// ClientRegistration은 OAuth 2 Client에 대한 등록 정보를 표현
return CommonOAuth2Provider
.GOOGLE
.getBuilder("google")
.clientId(clientId)
.clientSecret(clientSecret)
.build();
}
}
컨트롤러
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
@Controller
public class HelloHomeController {
@GetMapping("/hello-oauth2")
public String home(@RegisteredOAuth2AuthorizedClient("google") OAuth2AuthorizedClient authorizedClient) { // (1)
OAuth2AccessToken accessToken = authorizedClient.getAccessToken();
System.out.println("Access Token Value: " + accessToken.getTokenValue());
System.out.println("Access Token Type: " + accessToken.getTokenType().getValue());
System.out.println("Access Token Scopes: " + accessToken.getScopes());
System.out.println("Access Token Issued At: " + accessToken.getIssuedAt());
System.out.println("Access Token Expires At: " + accessToken.getExpiresAt());
return "hello-oauth2";
}
}