2 ๋ถ„ ์†Œ์š”

1. OAuth2ClientConfigurer ์ดˆ๊ธฐํ™” ๋ฐ ์„ค์ •

Image

Image

2. OAuth2AuthorizationCodeGrantFilter โ€“ Authorization Code Grant Support

โœ”๏ธ๊ฐœ๋…

  • Authorization Code Grant ๋ฐฉ์‹์œผ๋กœ ๊ถŒํ•œ ๋ถ€์—ฌ ์š”์ฒญ์„ ์ง€์›ํ•˜๋Š” ํ•„ํ„ฐ
  • ์ธ๊ฐ€์„œ๋ฒ„๋กœ๋ถ€ํ„ฐ ๋ฆฌ๋‹ค์ด๋ ‰ํŠธ ๋˜๋ฉด์„œ ์ „๋‹ฌ๋œ code ๋ฅผ ์ธ๊ฐ€์„œ๋ฒ„์˜ Access Token ์œผ๋กœ ๊ตํ™˜ํ•œ๋‹ค.
  • OAuth2AuthorizedClientRepository ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ OAuth2AuthorizedClient ๋ฅผ ์ €์žฅ ํ›„ ํด๋ผ์ด์–ธํŠธ์˜ Redirect Uri ๋กœ ์ด๋™ํ•œ๋‹ค
  • Image

  • ์‹คํ–‰ ์กฐ๊ฑด
    • ์š”์ฒญ ํŒŒ๋ผ๋ฏธํ„ฐ์— code ์™€ state ๊ฐ’์ด ์กด์žฌํ•˜๋Š”์ง€ ํ™•์ธ
    • OAuth2AuthorizationRequest ๊ฐ์ฒด๊ฐ€ ์กด์žฌํ•˜๋Š”์ง€ ํ™•์ธ

3. OAuth2AuthorizedClient โ€“ ๊ถŒํ•œ๋ถ€์—ฌ ํด๋ผ์ด์–ธํŠธ

โœ”๏ธ๊ฐœ๋…

  • OAuth2AuthorizedClient ๋Š” ์ธ๊ฐ€๋ฐ›์€ ํด๋ผ์ด์–ธํŠธ๋ฅผ ์˜๋ฏธํ•˜๋Š” ํด๋ž˜์Šค๋‹ค.
  • ์ตœ์ข… ์‚ฌ์šฉ์ž(๋ฆฌ์†Œ์Šค ์†Œ์œ ์ž)๊ฐ€ ํด๋ผ์ด์–ธํŠธ์—๊ฒŒ ๋ฆฌ์†Œ์Šค์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋Š” ๊ถŒํ•œ์„ ๋ถ€์—ฌํ•˜๋ฉด, ํด๋ผ์ด์–ธํŠธ๋ฅผ ์ธ๊ฐ€๋œ ํด๋ผ์ด์–ธํŠธ๋กœ ๊ฐ„์ฃผํ•œ๋‹ค
  • OAuth2AuthorizedClient ๋Š” AccessToken ๊ณผ RefreshToken ์„ ClientRegistration (ํด๋ผ์ด์–ธํŠธ)์™€ ๊ถŒํ•œ์„ ๋ถ€์—ฌํ•œ ์ตœ์ข… ์‚ฌ์šฉ์ž์ธ Principal๊ณผ ํ•จ๊ป˜ ๋ฌถ์–ด ์ค€๋‹ค
  • OAuth2AuthorizedClient ์˜ AccessToken ์„ ์‚ฌ์šฉํ•ด์„œ ๋ฆฌ์†Œ์Šค ์„œ๋ฒ„์˜ ์ž์›์— ์ ‘๊ทผ ํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ ์ธ๊ฐ€์„œ๋ฒ„์™€์˜ ํ†ต์‹ ์œผ๋กœ ํ† ํฐ์„ ๊ฒ€์ฆํ•  ์ˆ˜ ์žˆ๋‹ค
  • OAuth2AuthorizedClient ์˜ ClientRegistration ๊ณผ AccessToken ์„ ์‚ฌ์šฉํ•ด์„œ UserInfo ์—”๋“œ ํฌ์ธํŠธ๋กœ ์š”์ฒญํ•  ์ˆ˜ ์žˆ๋‹ค
  • Image

  • OAuth2AuthorizedClientRepository

    • OAuth2AuthorizedClientRepository ๋Š” ๋‹ค๋ฅธ ์›น ์š”์ฒญ์ด ์™€๋„ ๋™์ผํ•œ OAuth2AuthorizedClient ๋ฅผ ์œ ์ง€ํ•˜๋Š” ์—ญํ• ์„ ๋‹ด๋‹นํ•œ๋‹ค.
    • OAuth2AuthorizedClientService ์—๊ฒŒ OAuth2AuthorizedClient ์˜ ์ €์žฅ, ์กฐํšŒ, ์‚ญ์ œ ์ฒ˜๋ฆฌ๋ฅผ ์œ„์ž„ํ•œ๋‹ค
    • Image
  • OAuth2AuthorizedClientService

    • OAuth2AuthorizedClientService ๋Š” ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋ ˆ๋ฒจ์—์„œ OAuth2AuthorizedClient ๋ฅผ ๊ด€๋ฆฌ(์ €์žฅ, ์กฐํšŒ, ์‚ญ์ œ )ํ•˜๋Š” ์ผ์ด๋‹ค.
    • Image
  • ์›น ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ ํ™œ์šฉ
    • OAuth2AuthorizedClientRepository ๋‚˜ OAuth2AuthorizedClientService ๋Š” OAuth2AuthorizedClient ์—์„œ OAuth2AccessToken ์„ ์ฐพ์„ ์ˆ˜ ์žˆ๋Š” ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•˜๋ฏ€๋กœ ๋ณดํ˜ธ์ค‘์ธ ๋ฆฌ์†Œ์Šค ์š”์ฒญ์„ ์‹œ์ž‘ํ•  ๋•Œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค
    • Image

4. DefaultOAuth2AuthorizedClientManager โ€“ ํด๋ผ์ด์–ธํŠธ ์ธ๊ฐ€ ๊ด€๋ฆฌ์ž

4-1). ๊ฐœ๋…

โœ”๏ธ๊ฐœ๋…

  • OAuth2AuthorizedClient ๋ฅผ ์ „๋ฐ˜์ ์œผ๋กœ ๊ด€๋ฆฌํ•˜๋Š” ์ธํ„ฐํŽ˜์ด์Šค
  • OAuth2AuthorizedClientProvider ๋กœ OAuth 2.0 ํด๋ผ์ด์–ธํŠธ์— ๊ถŒํ•œ ๋ถ€์—ฌ
    • Client Credentials Flow
    • Resource Owner Password Flow
    • Refresh Token Flow
  • OAuth2AuthorizedClientService ๋‚˜ OAuth2AuthorizedClientRepository ์— OAuth2AuthorizedClient ์ €์žฅ์„ ์œ„์ž„ํ•œ ํ›„ OAuth2AuthorizedClient ์ตœ์ข… ๋ฐ˜ํ™˜
  • ์‚ฌ์šฉ์ž ์ •์˜ OAuth2AuthorizationSuccessHandler ๋ฐ OAuth2AuthorizationFailureHandler ๋ฅผ ๊ตฌ์„ฑํ•˜์—ฌ ์„ฑ๊ณต/์‹คํŒจ ์ฒ˜๋ฆฌ๋ฅผ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ๋‹ค.
  • invalid_grant ์˜ค๋ฅ˜๋กœ ์ธํ•ด ๊ถŒํ•œ ๋ถ€์—ฌ ์‹œ๋„๊ฐ€ ์‹คํŒจํ•˜๋ฉด ์ด์ „์— ์ €์žฅ๋œ OAuth2AuthorizedClient๊ฐ€ OAuth2AuthorizedClientRepository ์—์„œ ์ œ๊ฑฐ๋œ๋‹ค
  • Image

โœ”๏ธํŠน์ง•

Image

โœ”๏ธ๊ตฌ์กฐ

Image

โœ”๏ธ์ƒ์„ฑ

@Bean
public OAuth2AuthorizedClientManager authorizedClientManager(ClientRegistrationRepository clientRegistrationRepository,
OAuth2AuthorizedClientRepository authorizedClientRepository) {
	OAuth2AuthorizedClientProvider authorizedClientProvider =
		OAuth2AuthorizedClientProviderBuilder.builder()
			.authorizationCode()
			.refreshToken()
			.clientCredentials()
			.password()
			.build();

	DefaultOAuth2AuthorizedClientManager authorizedClientManager =
		new DefaultOAuth2AuthorizedClientManager(
			clientRegistrationRepository, authorizedClientRepository);
	authorizedClientManager.setAuthorizedClientProvider(authorizedClientProvider);

	return authorizedClientManager;
}

4-2). ์ธ๊ฐ€์„œ๋ฒ„์™€ ์—ฐ๋™ํ•˜์—ฌ ๋กœ๊ทธ์ธ ๊ตฌํ˜„

4-2-1). ๊ธฐ๋ณธ ํ™˜๊ฒฝ ๊ตฌ์„ฑ

โœ”๏ธ๊ฐœ์š”

  • ์Šคํ”„๋ง ์‹œํ๋ฆฌํ‹ฐ์˜ OAuth2Login ํ•„ํ„ฐ์— ์˜ํ•œ ์ž๋™ ์ธ์ฆ์ฒ˜๋ฆฌ๋ฅผ ํ•˜์ง€ ์•Š๊ณ  DefaultOAuth2AuthorizedClientManager ํด๋ž˜์Šค๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ Spring MVC ์—์„œ ์ง์ ‘ ์ธ์ฆ์ฒ˜๋ฆฌ๋ฅผ ํ•˜๋Š” ๋กœ๊ทธ์ธ ๊ธฐ๋Šฅ์„ ๊ตฌํ˜„ํ•œ๋‹ค.
@Bean
SecurityFilterChain oauth2SecurityFilterChain(HttpSecurity http) throws Exception {
	http.authorizeRequests((requests) -> requests.antMatchers("/","/oauth2Login","/client").permitAll().anyRequest().authenticated());
	http
		// .oauth2Login().and()
		.oauth2Client();
	http.logout().invalidateHttpSession(true)
		.deleteCookies("JSESSIONID")
		.clearAuthentication(true);

	return http.build();
}

โœ”๏ธ๊ธฐ๋ณธ ๊ตฌ์„ฑ

  • AppConfig โ€“ DefaultOAuth2AuthorizedClientManager ๋นˆ ์ƒ์„ฑ ๋ฐ ์„ค์ • ์ดˆ๊ธฐํ™”
  • DefaultOAuth2AuthorizedClientManager โ€“ OAuth2 ๊ถŒํ•œ ๋ถ€์—ฌ ํ๋ฆ„์„ ์ฒ˜๋ฆฌ
  • LoginController โ€“ DefaultOAuth2AuthorizedClientManager ๋ฅผ ์‚ฌ์šฉํ•ด์„œ ๋กœ๊ทธ์ธ ์ฒ˜๋ฆฌ
  • home.html โ€“ ์ธ์ฆ๋ฐ›์€ ์‚ฌ์šฉ์ž๋งŒ ์ ‘๊ทผ๊ฐ€๋Šฅ
  • Index.html, client.html โ€“ ์•„๋ฌด๋‚˜ ์ ‘๊ทผ ๊ฐ€๋Šฅ
  • application.yml - ๊ถŒํ•œ ๋ถ€์—ฌ ์œ ํ˜•์„ client_credentials, password, refresh ํƒ€์ž…์œผ๋กœ ์„ค์ •ํ•œ๋‹ค

โœ”๏ธ๋กœ๊ทธ์ธ ๊ตฌํ˜„ ์ˆœ์„œ

  1. DefaultOAuth2AuthorizedClientManager ๋นˆ ์ƒ์„ฑ ๋ฐ ํŒŒ๋ผ๋ฏธํ„ฐ ์ดˆ๊ธฐ ๊ฐ’๋“ค์„ ์ •์˜ํ•œ๋‹ค
  2. ๊ถŒํ•œ ๋ถ€์—ฌ ์œ ํ˜•์— ๋”ฐ๋ผ ์š”์ฒญ์ด ์ด๋ฃจ์–ด๋„๋ก application.yml ์„ค์ •์„ ์กฐ์ •ํ•œ๋‹ค
  3. /oauth2Login ์ฃผ์†Œ๋กœ ๊ถŒํ•œ ๋ถ€์—ฌ ํ๋ฆ„์„ ์š”์ฒญํ•œ๋‹ค
  4. DefaultOAuth2AuthorizedClientManager ์—๊ฒŒ ๊ถŒํ•œ ๋ถ€์—ฌ๋ฅผ ์š”์ฒญํ•œ๋‹ค
  5. ๊ถŒํ•œ ๋ถ€์—ฌ๊ฐ€ ์„ฑ๊ณตํ•˜๋ฉด OAuth2AuthorizationSuccessHandler ๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ์ธ์ฆ ์ดํ›„ ์ž‘์—…์„ ์ง„ํ–‰ํ•œ๋‹ค
    1. DefaultOAuth2AuthorizedClientManager ์˜ ์ตœ์ข… ๋ฐ˜ํ™˜๊ฐ’์ธ OAuth2AuthorizedClient ๋ฅผ OAuth2AuthorizedClientRepository ์— ์ €์žฅํ•œ๋‹ค
  6. OAuth2AuthorizedClient ์—์„œ Access Token ์„ ์ฐธ์กฐํ•˜์—ฌ /userinfo ์—”๋“œํฌ์ธํŠธ ์š”์ฒญ์œผ๋กœ ์ตœ์ข… ์‚ฌ์šฉ์ž ์ •๋ณด๋ฅผ ๊ฐ€์ ธ์˜จ๋‹ค
  7. ์‚ฌ์šฉ์ž ์ •๋ณด์™€ ๊ถŒํ•œ์„ ๊ฐ€์ง€๊ณ  ์ธ์ฆ๊ฐ์ฒด๋ฅผ ๋งŒ๋“  ํ›„ SecurityContext ์— ์ €์žฅํ•˜๊ณ  ์ธ์ฆ์„ ์™„๋ฃŒํ•œ๋‹ค
  8. ์ธ์ฆ์ด ์„ฑ๊ณตํ•˜๋ฉด
  9. 1~8 ๋ฒˆ์˜ ๊ณผ์ •์„ ์ปค์Šคํ…€ ํ•„ํ„ฐ๋ฅผ ๋งŒ๋“ค์–ด์„œ ์ฒ˜๋ฆฌํ•˜๋„๋ก ํ•œ๋‹ค

4-2-2). Client Credentials Flow

Image

4-2-3). Resource Owner Password Flow

Image

Image

4-2-4). Refresh Token Flow

Image

5. OAuth2 ์ปค์Šคํ…€ ๋กœ๊ทธ์ธ ํ•„ํ„ฐ ๊ตฌํ˜„

Image

6. @RegisteredOAuth2AuthorizedClient

โœ”๏ธ@RegisteredOAuth2AuthorizedClient

  • ํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ OAuth2AuthorizedClient ํƒ€์ž… ์ธ์ž๋กœ ๋ฆฌ์กธ๋ธŒํ•ด์ค€๋‹ค
  • OAuth2AuthorizedClientArgumentResolver ์—์„œ ์š”์ฒญ์„ ๊ฐ€๋กœ์ฑ„์–ด ์œ ํ˜•๋ณ„๋กœ ๊ถŒํ•œ ๋ถ€์—ฌ ํ๋ฆ„์„ ์‹คํ–‰ํ•˜๋„๋ก ํ•œ๋‹ค
  • ์ด ๋ฐฉ๋ฒ•์€ OAuth2AuthorizedClientManager ๋‚˜ OAuth2AuthorizedClientService ๋กœ OAuth2AuthorizedClient ์— ์ ‘๊ทผํ•˜๋Š” ๊ฒƒ๋ณด๋‹ค ํŽธ๋ฆฌํ•˜๋‹ค
    @GetMapping("/")
    public String index(@RegisteredOAuth2AuthorizedClient(โ€œkeycloak") OAuth2AuthorizedClient authorizedClient) {
    		OAuth2AccessToken accessToken = authorizedClient.getAccessToken();
    	return "index";
    }
    

    โžก๏ธ @RegisteredOAuth2AuthorizedClient ๋ฅผ ์„ ์–ธํ•˜๊ณ  OAuth2AuthorizedClient ๋ฅผ ์ธ์ž๋กœ ์ง€์ •ํ•œ ๋ฉ”์„œ๋“œ์ด๋ฉด OAuth2AuthorizedClientArgumentResolver ๊ฐ€ ์‹คํ–‰๋˜๋ฉด์„œ OAuth2AuthorizedClientManager ๋ฅผ ํ†ตํ•ด ์ธ๊ฐ€ ์ฒ˜๋ฆฌํ•œ๋‹ค Image

Image

์นดํ…Œ๊ณ ๋ฆฌ:

์—…๋ฐ์ดํŠธ:

๋Œ“๊ธ€๋‚จ๊ธฐ๊ธฐ