1. api-client , resource server
https://www.baeldung.com/spring-security-oauth-auth-server
baeldung gihub
https://github.com/Baeldung/spring-security-oauth/tree/master/oauth-authorization-server
2. api-client server ์์ค๋ถ์
2.1 yml ์ค์
server:
port: 8080
spring:
security:
oauth2:
client:
registration:
articles-client-oidc: #ํด๋ผ์ด์ธํธ ์ธ์ฆ
provider: spring
client-id: articles-client
client-secret: secret
authorization-grant-type: authorization_code
redirect-uri: "http://127.0.0.1:8080/login/oauth2/code/{registrationId}"
scope: openid
client-name: articles-client-oidc
articles-client-authorization-code: #ํด๋ผ์ด์ธํธ ์ฝ๋๋ก ์ก์ธ์ค ํ ํฐ ์์ฒญ์ ์ฌ์ฉ
provider: spring
client-id: articles-client
client-secret: secret
authorization-grant-type: authorization_code
redirect-uri: "http://127.0.0.1:8080/authorized"
scope: articles.read
client-name: articles-client-authorization-code
provider:
spring:
issuer-uri: http://auth-server:9000
2.1.1 ์์ฒญ ์๋ต ํ๋ฆ (์ํ์ค)
- ์ฌ์ฉ์ ๋ก๊ทธ์ธ ์์ฒญ: ์ฌ์ฉ์๊ฐ ์ ํ๋ฆฌ์ผ์ด์ ์ ๋ก๊ทธ์ธ์ ์๋ํฉ๋๋ค.
-
๋ฆฌ๋ค์ด๋ ์
: ํด๋ผ์ด์ธํธ ์ ํ๋ฆฌ์ผ์ด์
์ ์ฌ์ฉ์๋ฅผ ์ธ์ฆ ์๋ฒ์ ๋ก๊ทธ์ธ ํ์ด์ง๋ก ๋ฆฌ๋ค์ด๋ ์
ํฉ๋๋ค. ์ด ๋
client-id
,redirect-uri
,scope
๋ฑ์ ์ ๋ณด๊ฐ ํฌํจ๋ฉ๋๋ค. ์ด ์ ๋ณด๋registration
์น์ ์์ ์ ์๋ฉ๋๋ค. -
์ฌ์ฉ์ ์ธ์ฆ: ์ฌ์ฉ์๋ ์ธ์ฆ ์๋ฒ์์ ๋ก๊ทธ์ธ์ ์งํํฉ๋๋ค. ์ด ๊ณผ์ ์์
issuer-uri
(์ธ์ฆ ์๋ฒ ์ฃผ์)๊ฐ ์ฌ์ฉ๋ฉ๋๋ค. -
์ธ์ฆ ์ฝ๋ ๋ฐ๊ธ: ๋ก๊ทธ์ธ์ด ์ฑ๊ณตํ๋ฉด ์ธ์ฆ ์๋ฒ๋
redirect-uri
๋ก ์ฌ์ฉ์๋ฅผ ๋ค์ ๋ฆฌ๋ค์ด๋ ์ ํ๋ฉฐ, ์ด ๋ ์ธ์ฆ ์ฝ๋๋ฅผ ํจ๊ป ์ ๋ฌํฉ๋๋ค. -
์ธ์ฆ ์ฝ๋๋ฅผ ํ ํฐ์ผ๋ก ๊ตํ: ํด๋ผ์ด์ธํธ ์ ํ๋ฆฌ์ผ์ด์
์ ๋ฐ์ ์ธ์ฆ ์ฝ๋๋ฅผ ์ฌ์ฉํ์ฌ ์ธ์ฆ ์๋ฒ์ ํ ํฐ์ ์์ฒญํฉ๋๋ค. ์ฌ๊ธฐ์
client-id
๋ฐclient-secret
์ด ์ฌ์ฉ๋ฉ๋๋ค. - ํ ํฐ ์๋ต: ์ธ์ฆ ์๋ฒ๋ ํด๋ผ์ด์ธํธ์๊ฒ ์ก์ธ์ค ํ ํฐ(๋ฐ ํ์์ ๋ฆฌํ๋ ์ ํ ํฐ)์ ๋ฐ๊ธํฉ๋๋ค.
-
๋ฆฌ์์ค ์๋ฒ ์ ๊ทผ: ํด๋ผ์ด์ธํธ๋ ๋ฐ์ ํ ํฐ์ ์ฌ์ฉํ์ฌ ๋ณดํธ๋ ๋ฆฌ์์ค์ ์ก์ธ์คํฉ๋๋ค. ์๋ฅผ ๋ค์ด,
scope: articles.read
๋ฅผ ์ฌ์ฉํ์ฌ ํน์ API์ ์ ๊ทผํ ์ ์์ต๋๋ค.
2.1.2 ์ค์ ํ์ผ ๋ด์ ์ญํ
-
client-id
๋ฐclient-secret
: ํด๋ผ์ด์ธํธ์ ์ ์์ ์ธ์ฆ ์๋ฒ์ ์ฆ๋ช ํ๋๋ฐ ์ฌ์ฉ๋ฉ๋๋ค. -
redirect-uri
: ์ฌ์ฉ์๊ฐ ์ธ์ฆ ํ ๋ฆฌ๋ค์ด๋ ์ ๋ URI์ ๋๋ค. ์ธ์ฆ ์ฝ๋๋ฅผ ๋ฐ๋ ๋ฐ ์ฌ์ฉ๋ฉ๋๋ค. -
scope
: ํด๋ผ์ด์ธํธ๊ฐ ์์ฒญํ ์ ์๋ ๊ถํ์ ๋ฒ์๋ฅผ ์ ์ํฉ๋๋ค. -
issuer-uri
: ์ธ์ฆ ์๋ฒ์ ์ฃผ์์ ๋๋ค. ์ฌ์ฉ์ ์ธ์ฆ ๋ฐ ํ ํฐ ๋ฐ๊ธ์ ์ฌ์ฉ๋ฉ๋๋ค.
2.1.3 ์์ธ์ค๋ช
-
articles-client-oidc
: ์ต์ด ํด๋ผ์ด์ธํธ ์ธ์ฆ- ์ด ์ค์ ์ ์ฌ์ฉ์๊ฐ ์ต์ด๋ก ๋ก๊ทธ์ธํ ๋ ์ฌ์ฉ๋ฉ๋๋ค.
- ์ฌ์ฉ์๊ฐ ์ ํ๋ฆฌ์ผ์ด์ ์ ๋ก๊ทธ์ธ์ ์์ฒญํ๋ฉด, ์ ํ๋ฆฌ์ผ์ด์ ์ ์ฌ์ฉ์๋ฅผ OAuth 2.0 ์ธ์ฆ ์๋ฒ์ ๋ก๊ทธ์ธ ํ์ด์ง๋ก ๋ฆฌ๋ค์ด๋ ์ ํฉ๋๋ค.
-
articles-client-oidc
์ค์ ์ ํฌํจ๋client-id
,client-secret
,redirect-uri
,scope
๋ฑ์ ์ ๋ณด๊ฐ ์ด ๊ณผ์ ์์ ์ฌ์ฉ๋ฉ๋๋ค. - ์ฌ์ฉ์๊ฐ ์ธ์ฆ ์๋ฒ์์ ์ฑ๊ณต์ ์ผ๋ก ์ธ์ฆ์ ์๋ฃํ๋ฉด, ์ธ์ฆ ์๋ฒ๋
redirect-uri
๋ก ์ฌ์ฉ์๋ฅผ ๋ฆฌ๋๋ ์ ํ๊ณ ์ธ์ฆ ์ฝ๋๋ฅผ ์ ๊ณตํฉ๋๋ค.
-
articles-client-authorization-code
: ๋ฆฌ์์ค ์๋ฒ์ ๋ํ ์์ฒญ- ์ธ์ฆ ์ฝ๋๋ฅผ ๋ฐ์ ํ, ์ ํ๋ฆฌ์ผ์ด์
์ ์ด ์ฝ๋๋ฅผ ์ฌ์ฉํ์ฌ ์ธ์ฆ ์๋ฒ์ ์ก์ธ์ค ํ ํฐ์ ์์ฒญํฉ๋๋ค. ์ด ๋
articles-client-authorization-code
์ค์ ์ด ์ฌ์ฉ๋ฉ๋๋ค. -
client-id
,client-secret
๋ ์ด ๊ณผ์ ์์ ํ ํฐ ๊ตํ์ ์ํด ์ฌ์ฉ๋๋ฉฐ,redirect-uri
๋ ์ด์ ๋จ๊ณ์์ ์ธ์ฆ ์ฝ๋๋ฅผ ๋ฐ๊ธฐ ์ํด ์ฌ์ฉ๋ ์ฃผ์์ ๋๋ค. - ์ ํ๋ฆฌ์ผ์ด์
์ด ์ก์ธ์ค ํ ํฐ์ ๋ฐ์ผ๋ฉด, ์ด ํ ํฐ์ ์ฌ์ฉํ์ฌ ๋ณดํธ๋ ๋ฆฌ์์ค์ ์ ๊ทผํ ์ ์์ต๋๋ค. ์ด ๊ฒฝ์ฐ
scope: articles.read
์ ๋ฐ๋ผ ํน์ ๋ฆฌ์์ค์ ๋ํ ์ก์ธ์ค ๊ถํ์ด ๋ถ์ฌ๋ฉ๋๋ค.
- ์ธ์ฆ ์ฝ๋๋ฅผ ๋ฐ์ ํ, ์ ํ๋ฆฌ์ผ์ด์
์ ์ด ์ฝ๋๋ฅผ ์ฌ์ฉํ์ฌ ์ธ์ฆ ์๋ฒ์ ์ก์ธ์ค ํ ํฐ์ ์์ฒญํฉ๋๋ค. ์ด ๋
์์ฝํ์๋ฉด, articles-client-oidc
์ค์ ์ ์ฌ์ฉ์ ์ธ์ฆ์ ์ํ ์ด๊ธฐ ๋ก๊ทธ์ธ ๊ณผ์ ์ ์ฌ์ฉ๋๋ฉฐ, articles-client-authorization-code
์ค์ ์ ์ธ์ฆ๋ ์ฌ์ฉ์๊ฐ ๋ณดํธ๋ ๋ฆฌ์์ค์ ์ ๊ทผํ๊ธฐ ์ํด ํ์ํ ์ก์ธ์ค ํ ํฐ์ ์ป๋ ๊ณผ์ ์ ์ฌ์ฉ
2.2 ์์ค
@EnableWebSecurity
public class SecurityConfig {
@Bean
SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.authorizeRequests(authorizeRequests ->
authorizeRequests.anyRequest().authenticated()
)
.oauth2Login(oauth2Login ->
oauth2Login.loginPage("/oauth2/authorization/articles-client-oidc"))
.oauth2Client(withDefaults());
return http.build();
}
}
oauth2Login.loginPage("/oauth2/authorization/articles-client-oidc"))
ํด๋น ํ์ด์ง๋ ํด๋ผ์ด์ธํธ ์๋ฒ์์ ์ ๊ณต๋๋ ํ์ด์ง์ด๋ฉฐ, security5์ ์ ๊ณต๋๋ ํ์ด์ง๋ก ์ฌ์ฉ๋๊ฑฐ.
@RestController
public class ArticlesController {
private WebClient webClient;
@GetMapping(value = "/articles")
public String[] getArticles(
@RegisteredOAuth2AuthorizedClient("articles-client-authorization-code") OAuth2AuthorizedClient authorizedClient
) {
return this.webClient
.get()
.uri("http://127.0.0.1:8090/articles")
.attributes(oauth2AuthorizedClient(authorizedClient))
.retrieve()
.bodyToMono(String[].class)
.block();
}
}
OAuth2AuthorizedClientย ํด๋์ค ํ์์ ์์ฒญ์์ OAuth ์ธ์ฆ ํ ํฐ์ ๊ฐ์ ธ์ต๋๋คย .ย
์ด๋ ์ ์ ํ ์๋ณ๊ณผ ํจ๊ปย @RegisterdOAuth2AuthorizedClientย ์ฃผ์์ ์ฌ์ฉํ์ฌ Spring์ ์ํด ์๋์ผ๋ก ๋ฐ์ธ๋ฉ๋ฉ๋๋ค .ย ์ฐ๋ฆฌ์ ๊ฒฝ์ฐ ์ด์ ์ .ymlย ํ์ผ ์์ ๊ตฌ์ฑํย article-client-authorizaiton-codeย ์์ ๊ฐ์ ธ์์ต๋๋ค
3. ํ ์คํธ ํธ์ถ
๋ธ๋ผ์ฐ์ ์์ ํธ์ถ http://127.0.0.1:8080/articles
์ธ์ฆ url ๋ก ๋ฆฌ๋ค์ด๋ ์ http://auth-server:9000/login
4. ๋ฆฌ์์ค ์๋ฒ
๋ณด์๊ตฌ์ฑ - ์ธ์ฆ์๋ฒ ์ค์
์ธ์ฆ์๋ฒ์ ์ค์ ํ ProviderSettings ๊ฐ์ issuer-uri ๋ก ์ค์
spring:
security:
oauth2:
resourceserver:
jwt:
issuer-uri: http://auth-server:9000
์น๋ณด์ ๊ตฌ์ฑ ์ค์ : ๋ฆฌ์์ค์ ๋ํ ๊ถํ ์ค์ ( ์ฝ๊ธฐ, ๋ชจ๋ ์์ฒญ์ ๋ํ ์น์ธ์์ฒญ)
@EnableWebSecurity
public class ResourceServerConfig {
@Bean
SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http.mvcMatcher("/articles/**")
.authorizeRequests() //1.์์ฒญ์ ๋ํ ์ธ์ฆ์ ์์ํฉ๋๋ค. ์ด ๋จ๊ณ์์๋ ์ดํ์ ์ ์๋ ์ธ์ฆ ๊ท์น๋ค์ด ์ ์ฉ๋ฉ๋๋ค
.mvcMatchers("/articles/**")//2.ํน์ ๊ฒฝ๋ก(/articles/**)์ ๋ํ ์ถ๊ฐ์ ์ธ ๊ท์น์ ์ ์.
// ํด๋น ๊ฒฝ๋ก์ ๋ํ ๋ณด์ ๊ท์น์ ์ธ๋ถํ
.access("hasAuthority('SCOPE_articles.read')")//3./articles/** ๊ฒฝ๋ก์ ๋ํ ์ ๊ทผ์ ์ ์ด
// 'SCOPE_articles.read' ๊ถํ์ ๊ฐ์ง๊ณ ์์ด์ผ๋ง ํด๋น ๊ฒฝ๋ก์ ์ ๊ทผ ๊ฐ๋ฅ
// ์ด ๊ถํ์ ์ผ๋ฐ์ ์ผ๋ก OAuth 2.0 ํ ํฐ์ ์ ์๋ ์ค์ฝํ์์ ํ์๋ฉ๋๋ค.
.and()
.oauth2ResourceServer() //3. OAuth 2.0 ๋ฆฌ์์ค ์๋ฒ๋ฅผ ํ์ฑํํ๊ณ JWT (JSON Web Token)๋ฅผ ์ฌ์ฉํ์ฌ ์ธ์ฆ์ ์ํ
.jwt(); // ๋ค์ด์ค๋ ์์ฒญ์ด ์ฌ๋ฐ๋ฅธ JWT๋ฅผ ํฌํจํ๊ณ ์๋์ง ๊ฒ์ฆํ์ฌ ํด๋น ์์ฒญ์ด ์ ํจํ์ง ํ์ธ
return http.build();
}
}
5. ์ธ์ฆ์๋ฒ
@Configuration
@Import(OAuth2AuthorizationServerConfiguration.class)
public class AuthorizationServerConfig {
@Bean
public RegisteredClientRepository registeredClientRepository() {
RegisteredClient registeredClient = RegisteredClient.withId(UUID.randomUUID().toString())
.clientId("articles-client")
.clientSecret("{noop}secret")
.clientAuthenticationMethod(ClientAuthenticationMethod.CLIENT_SECRET_BASIC)
.authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE)
.authorizationGrantType(AuthorizationGrantType.REFRESH_TOKEN)
.redirectUri("http://127.0.0.1:8080/login/oauth2/code/articles-client-oidc")
.redirectUri("http://127.0.0.1:8080/authorized")
.scope(OidcScopes.OPENID)
.scope("articles.read")
.build();
return new InMemoryRegisteredClientRepository(registeredClient);
}
}
-
RegisteredClient.withId(UUID.randomUUID().toString())
: ํด๋ผ์ด์ธํธ ID๋ฅผ ์์ฑํฉ๋๋ค. ์ฌ๊ธฐ์๋ ๊ณ ์ ํ UUID๋ฅผ ์ฌ์ฉํฉ๋๋ค. -
.clientId("articles-client")
: OAuth ํด๋ผ์ด์ธํธ์ ์๋ณ์๋ก "articles-client"๋ฅผ ์ง์ ํฉ๋๋ค. Spring์ ์ด๋ฅผ ์ฌ์ฉํ์ฌ ๋ฆฌ์์ค์ ์ก์ธ์คํ๋ ค๋ ํด๋ผ์ด์ธํธ๋ฅผ ์๋ณํฉ๋๋ค. -
.clientSecret("{noop}secret")
: ํด๋ผ์ด์ธํธ์ ๋น๋ฐ๋ฒํธ๋ฅผ ์ค์ ํฉ๋๋ค.{noop}
์ ํจ์ค์๋ ์ธ์ฝ๋๊ฐ ์ฌ์ฉ๋์ง ์์์ ์๋ฏธํฉ๋๋ค. -
.clientAuthenticationMethod(ClientAuthenticationMethod.CLIENT_SECRET_BASIC)
: ํด๋ผ์ด์ธํธ ์ธ์ฆ ๋ฐฉ์์CLIENT_SECRET_BASIC
์ผ๋ก ์ค์ ํฉ๋๋ค. ์ด๋ ํด๋ผ์ด์ธํธ ID์ ๋น๋ฐ๋ฒํธ๋ฅผ ์ฌ์ฉํ์ฌ ์ธ์ฆ์ ์ํํ๋ ๋ฐฉ์์ ๋๋ค. -
.authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE)
(์ธ์ฆ ๋ถ์ฌ ์ ํ): ์ธ์ฆ ์ฝ๋ ๋ถ์ฌ ์ ํ์ ์ง์ํฉ๋๋ค. ์ด๋ OAuth 2.0์ ํ์ค ํ๋ก์ฐ ์ค ํ๋์ ๋๋ค. -
.authorizationGrantType(AuthorizationGrantType.REFRESH_TOKEN)
(์ธ์ฆ ๋ถ์ฌ ์ ํ): ๋ฆฌํ๋ ์ ํ ํฐ ๋ถ์ฌ ์ ํ์ ์ง์ํฉ๋๋ค. ์ด๋ฅผ ํตํด ํด๋ผ์ด์ธํธ๋ ์ก์ธ์ค ํ ํฐ์ ๊ฐฑ์ ํ ์ ์์ต๋๋ค. -
.redirectUri("http://127.0.0.1:8080/login/oauth2/code/articles-client-oidc")
: OAuth ์ธ์ฆ ํ ์ฌ์ฉ์๋ฅผ ๋ฆฌ๋๋ ์ ํ URI๋ฅผ ์ค์ ํฉ๋๋ค. -
.redirectUri("http://127.0.0.1:8080/authorized")
: ์ถ๊ฐ์ ์ธ ๋ฆฌ๋๋ ์ URI๋ฅผ ์ค์ ํฉ๋๋ค. -
.scope(OidcScopes.OPENID)
: OpenID Connect ์ค์ฝํ๋ฅผ ์ฌ์ฉํฉ๋๋ค. -
.scope("articles.read")
: ์ฌ์ฉ์ ์ ์ ์ค์ฝํ์ธ "articles.read"๋ฅผ ์ค์ ํฉ๋๋ค. ์ด ์ค์ฝํ๋ ํด๋ผ์ด์ธํธ๊ฐ ํน์ ์์์ ์ ๊ทผํ ์ ์๋๋ก ํ์ฉํฉ๋๋ค. -
.build()
:RegisteredClient
๊ตฌ์ฑ์ ์์ฑํฉ๋๋ค.
5.1 ์์ธ
.redirectUri
์ค์ ์ ๋ํด ์ค๋ช
๋๋ฆฌ๊ฒ ์ต๋๋ค. ์ด ์ค์ ์ OAuth 2.0 ์ธ์ฆ ํ๋ก์ธ์ค์์ ๋งค์ฐ ์ค์ํ ๋ถ๋ถ์
๋๋ค.
5.1.1. ์ธ์ฆ ์ฝ๋ ํ๋ฆ (Authorization Code Flow):
- .redirectUri("http://127.0.0.1:8080/login/oauth2/code/articles-client-oidc")
: ์ด ๋ฆฌ๋๋ ์
URI๋ ์ผ๋ฐ์ ์ผ๋ก ์ธ์ฆ ์ฝ๋ ํ๋ฆ์ ์ฌ์ฉ๋ฉ๋๋ค. ์ฌ์ฉ์๊ฐ OAuth ์ธ์ฆ์ ์์ํ๋ฉด, ์ฌ์ฉ์๋ ์ด URI๋ก ๋ฆฌ๋๋ ์
๋ฉ๋๋ค. ์ฌ๊ธฐ์ ์ฌ์ฉ์๋ ๋ก๊ทธ์ธํ๊ณ ๋์๋ฅผ ์ ๊ณตํ ํ, ์ธ์ฆ ์๋ฒ๋ ์ด URI๋ก ์ธ์ฆ ์ฝ๋๋ฅผ ๋ฆฌ๋๋ ์
ํฉ๋๋ค. ์ด ์ธ์ฆ ์ฝ๋๋ ๋์ค์ ์ก์ธ์ค ํ ํฐ์ ์ป๋ ๋ฐ ์ฌ์ฉ๋ฉ๋๋ค.
5.1.2. ์ก์ธ์ค ํ ํฐ ์์ฒญ:
- .redirectUri("http://127.0.0.1:8080/authorized")
: ์ด URI๋ ์ก์ธ์ค ํ ํฐ์ ๋ฐ๊ธฐ ์ํ ์ถ๊ฐ์ ์ธ ๋ฆฌ๋๋ ์
ํฌ์ธํธ๋ก ์ฌ์ฉ๋ ์ ์์ต๋๋ค. ์ฌ์ฉ์๊ฐ ์ธ์ฆ ์ฝ๋๋ฅผ ์ฌ์ฉํ์ฌ ์ก์ธ์ค ํ ํฐ์ ์์ฒญํ ๋, ์ธ์ฆ ์๋ฒ๋ ์ด URI๋ก ์ฌ์ฉ์๋ฅผ ๋ฆฌ๋๋ ์
ํ ์ ์์ต๋๋ค.
๋ฆฌ๋๋ ์
URI์ ์์๋ ์ผ๋ฐ์ ์ผ๋ก ์ค์ํ์ง ์์ต๋๋ค. ์ค์ํ ๊ฒ์ ํด๋ผ์ด์ธํธ ์ ํ๋ฆฌ์ผ์ด์
์ด ์ด URI๋ค ์ค ํ๋๋ฅผ ์ฌ์ฉํ์ฌ ์ธ์ฆ ์๋ฒ์ ๋ฆฌ๋๋ ์
์ ์์ฒญํ๋ ๊ฒ์
๋๋ค. ํด๋ผ์ด์ธํธ ์ ํ๋ฆฌ์ผ์ด์
์ด ์ธ์ฆ ์์ฒญ ์์ ์ฌ์ฉํ๋ redirect_uri
๋งค๊ฐ๋ณ์์ ๊ฐ์ ๋ฑ๋ก๋ ๋ฆฌ๋๋ ์
URI ์ค ํ๋์ ์ ํํ ์ผ์นํด์ผ ํฉ๋๋ค.
์์ฝํ์๋ฉด, .redirectUri("http://127.0.0.1:8080/login/oauth2/code/articles-client-oidc")
๋ ์ฌ์ฉ์๊ฐ ๋ก๊ทธ์ธํ๊ณ ์ธ์ฆ ์๋ฒ๊ฐ ์ธ์ฆ ์ฝ๋๋ฅผ ๋ฐํํ๋ ๋ฐ ์ฌ์ฉ๋๋ฉฐ, .redirectUri("http://127.0.0.1:8080/authorized")
๋ ์ถ๊ฐ์ ์ธ ๋ฆฌ๋๋ ์
์ต์
์ผ๋ก, ํน์ ์ํฉ์์ ์ฌ์ฉ๋ ์ ์์ต๋๋ค. ์ด ๋ URI๋ ์ธ์ฆ ํ๋ก์ธ์ค์ ๋ค๋ฅธ ๋จ๊ณ์์ ์ฌ์ฉ๋๋ฉฐ, ๊ทธ ์์๋ ํน๋ณํ ์๋ฏธ๋ฅผ ๊ฐ์ง์ง ์์ต๋๋ค.
5.2 ๊ตฌ์ฑ
๊ธฐ๋ณธ OAuth ๋ณด์์ ์ ์ฉํ๊ณ ๊ธฐ๋ณธ ์์ ๋ก๊ทธ์ธ ํ์ด์ง๋ฅผ ์์ฑํ๋๋ก Bean์ ๊ตฌ์ฑ
@Bean
@Order(Ordered.HIGHEST_PRECEDENCE)
public SecurityFilterChain authServerSecurityFilterChain(HttpSecurity http) throws Exception {
OAuth2AuthorizationServerConfiguration.applyDefaultSecurity(http);
return http.formLogin(Customizer.withDefaults()).build();
}
๊ฐ ์ธ์ฆ ์๋ฒ์๋ ๋ณด์ ๋๋ฉ์ธ ๊ฐ์ ์ ์ ํ ๊ฒฝ๊ณ๋ฅผ ์ ์งํ๊ธฐ ์ํด ํ ํฐ์ ๋ํ ์๋ช
ํค๊ฐ ํ์ํฉ๋๋ค.ย 2048๋ฐ์ดํธ RSA ํค๋ฅผ ์์ฑํด ๋ณด๊ฒ ์ต๋๋ค.
@Bean
public JWKSource<SecurityContext> jwkSource() {
RSAKey rsaKey = generateRsa();
JWKSet jwkSet = new JWKSet(rsaKey);
return (jwkSelector, securityContext) -> jwkSelector.select(jwkSet);
}
private static RSAKey generateRsa() {
KeyPair keyPair = generateRsaKey();
RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
return new RSAKey.Builder(publicKey)
.privateKey(privateKey)
.keyID(UUID.randomUUID().toString())
.build();
}
private static KeyPair generateRsaKey() {
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
keyPairGenerator.initialize(2048);
return keyPairGenerator.generateKeyPair();
}
์๋ช
ํค๋ฅผ ์ ์ธํ๊ณ ๊ฐ ์ธ์ฆ ์๋ฒ์๋ ๊ณ ์ ํ ๋ฐ๊ธ์ URL๋ ์์ด์ผ ํฉ๋๋ค.ย ProviderSettingsย ๋น์ ์์ฑํ์ฌย ํฌํธย 9000 ์์ย http://auth-serverย ์ ๋ํ localhost ๋ณ์นญ์ผ๋ก ์ค์ ํ๊ฒ ์ต๋๋คย .
@Bean
public ProviderSettings providerSettings() {
return ProviderSettings.builder()
.issuer("http://auth-server:9000")
.build();
}
๋ํย /etc/hosts ํ์ผ์ "ย 127.0.0.1 auth-serverย " ํญ๋ชฉ์ ์ถ๊ฐํ๊ฒ ์ต๋๋คย .ย ์ด๋ฅผ ํตํด ๋ก์ปฌ ์ปดํจํฐ์์ ํด๋ผ์ด์ธํธ์ ์ธ์ฆ ์๋ฒ๋ฅผ ์คํํ ์ ์์ผ๋ฉฐ ๋ ์ฌ์ด์ ์ธ์ ์ฟ ํค ๋ฎ์ด์ฐ๊ธฐ ๋ฌธ์ ๋ฅผ ํผํ ์ ์์ต๋๋ค.
๊ทธ๋ฐ ๋ค์ @EnableWebSecurityย ์ฃผ์์ด ๋ฌ๋ฆฐ ๊ตฌ์ฑ ํด๋์ค ๋ฅผ ์ฌ์ฉํ์ฌ Spring ์น ๋ณด์ ๋ชจ๋์ ํ์ฑํํฉ๋๋ค
@EnableWebSecurity
public class DefaultSecurityConfig {
@Bean
SecurityFilterChain defaultSecurityFilterChain(HttpSecurity http) throws Exception {
http.authorizeRequests(authorizeRequests ->
authorizeRequests.anyRequest().authenticated()
)
.formLogin(withDefaults());
return http.build();
}
// ...
}
- ๋ชจ๋ ์์ฒญ์ ๋ํด ์ธ์ฆ์ ์๊ตฌํ๊ธฐ ์ํดย AuthorizeRequests.anyRequest().authenticated()๋ฅผย ํธ์ถ
- formLogin(defaults())ย ๋ฉ์๋ ๋ฅผ ํธ์ถํ์ฌ ์์ ๊ธฐ๋ฐ ์ธ์ฆ์ ์ ๊ณตํ๊ณ
ํ
์คํธ์ ์ฌ์ฉํ ์์ ์ฌ์ฉ์ ์งํฉ์ ์ ์
@Bean
UserDetailsService users() {
UserDetails user = User.withDefaultPasswordEncoder()
.username("admin")
.password("password")
.build();
return new InMemoryUserDetailsManager(user);
}
Top comments (0)