Spring Security ‐ OAuth 2.0 Client Fundamentals - dnwls16071/Backend_Summary GitHub Wiki
📚 application.yml / OAuth2ClientProperties
클라이언트가 권한 부여 요청을 시작
- 클라이언트가 인가 서버로 권한 부여 요청을 하거나 토큰 요청을 할 경우 클라이언트 정보 및 엔드포인트 정보를 참조해서 전달한다.
- application.yml 환경설정 파일에 클라이언트 설정과 인가 서버 엔드포인트 설정을 한다.
- 초기화가 진행되면 application.yml에 있는 클라이언트 및 엔드 포인트 정보가 OAuth2ClientProperties의 각 속성에 바인딩이 된다.
- OAuth2ClientProperties에 바인딩된 속성의 값은 인가 서버로 권한 부여 요청을 하기 위한 ClientRegistration 클래스의 필드에 저장된다.
- OAuth2Client는 ClientRegistration을 참조해서 권한 부여 요청을 위한 매개변수를 구성하고 인가 서버와 통신한다.
server:
port: 8081 # keycloak와 충돌하지 않도록 포트 변경
spring:
security:
oauth2:
client:
registration:
keycloak:
clientId: oauth2-client-app # 서비스 공급자에 등록된 클라이언트 아이디
clientSecret: dXf021lMWuZ9kZafqxZn230MvVEdROIo # 서비스 공급자에 등록된 클라이언트 비밀번호
clientName: oauth2-client-app # 클라이언트 이름
redirectUri: http://localhost:8081/login/oauth2/code/keycloak # 인가 서버에서 권한 코드 부여 후 클라이언트로 리디렉션할 URI
authorizationGrantType: authorization_code # OAuth 2.0 권한 부여 타입
clientAuthenticationMethod: client_secret_basic # 클라이언트 자격증명 전송 방식
scope: openid,profile,email # 리소스 접근 제한 범위
provider:
keycloak:
authorizationUri: http://localhost:8080/realms/oauth2/protocol/openid-connect/auth # OAuth 2.0 권한 코드 부여 엔드포인트
tokenUri: http://localhost:8080/realms/oauth2/protocol/openid-connect/token # OAuth 2.0 토큰 엔드 포인트
issuerUri: http://localhost:8080/realms/oauth2 # 서비스 공급자 위치
userInfoUri: http://localhost:8080/realms/oauth2/protocol/openid-connect/userinfo # OAuth 2.0 UserInfo 엔드 포인트
jwkSetUri: http://localhost:8080/realms/oauth2/protocol/openid-connect/certs # OAuth 2.0 JwkSetUri 엔드 포인트
userNameAttribute: preferred_username # OAuth 2.0 사용자명을 추출하는 클레임명
📚 ClientRegistration
- OAuth 2.0 또는 OpenID Connect 1.0 Provider에서 클라이언트의 등록 정보를 나타낸다.
- ClientRegistration은 OpenID Connect Provider 설정 엔드 포인트나 인가 서버의 메타데이터 엔드 포인트를 찾아 초기화할 수 있다.
- ClientRegistration의 메서드를 사용하면 ClientRegistration을 설정할 수 있다.
각 내용 정리
registrationId : ClientRegistration을 식별할 수 있는 유니크한 ID
clientId : 클라이언트 식별자
clientSecret : 클라이언트 Secret
clientAuthenticationMethod : provider에서 클라이언트를 인증할 때 사용할 메서드로서 basic, post, none을 지원한다.
authorizationGrantType : OAuth 2.0 인가 프레임워크는 네 가지 권한 부여 타입을 정의하고 있으며 지원하는 값은 authorization_code, implicit, client_credentials, password이다.
redirectUriTemplate : 클라이언트에 등록한 리다이렉트 URL로, 사용자의 인증으로 클라이언트에 접근 권한을 부여하고 나면, 인가 서버가 이 URL로 최종 사용자의 브라우저를 리다이렉트시킨다.
Scopes : 인가 요청 플로우에서 클라이언트가 요청한 openid, 이메일, 프로필 등의 scope
clientName : 클라이언트를 나타내는 이름으로 자동 생성되는 로그인 페이지에서 노출하는 등에 사용한다.
authorizationUri : : 인가 서버의 인가 엔드포인트 URI.
tokenUri : 인가 서버의 토큰 엔드포인트 URI.
jwkSetUri : 인가 서버에서 JSON 웹 키 (JWK) 셋을 가져올 때 사용할 URI. 이 키 셋엔 ID 토큰의 JSON Web Signature (JWS) 를 검증할 때 사용할 암호키가 있으며, UserInfo 응답을 검증할 때도 사용할 수 있다
configurationMetadata : OpenID Provider 설정 정보로서 application.properties에 spring.security.oauth2.client.provider.[providerId].issuerUri를 설정했을 때만 사용할 수 있다.
(userInfoEndpoint)uri : 인증된 최종 사용자의 클레임/속성에 접근할 때 사용하는 UserInfo 엔드포인트 URI.
(userInfoEndPoint)authenticationMethod : UserInfo 엔드포인트로 액세스 토큰을 전송할 때 사용할 인증 메소드. header, form, query를 지원한다
userNameAttributeName : UserInfo 응답에 있는 속성 이름으로, 최종 사용자의 이름이나 식별자에 접근할 때 사용한다.
- CommonOAuth2Provider 클래스의 일부이다.
- OAuth 2.0 공급자 정보를 제공하는 클래스로서 글로벌 서비스 제공자 일부는 기본으로 제공된다.
- Client ID나 Client Secret는 별도로 작성해야 한다.
- Naver나 Kakao와 같은 국내 공급자 정보를 모든 항목을 수동으로 작성해야 한다.
- 클라이언트 기준인 Registration 항목과 서비스 제공자 기준인 Provider 항목으로 구분해서 설정한다.
- Java Config 방식으로 ClientRegistration을 등록할 수 있다.
- ClientRegistration 객체를 생성할 수 있는 빌더 클래스를 반환한다.
📚 ClientRegistrationRepository
- ClientRegistrationRepository는 OAuth 2.0 & OpenID Connect 1.0의 ClientRegistration 저장소 역할을 한다.
- 클라이언트 등록 정보는 궁극적으로 인가 서버가 저장하고 관리하는데 이 레포지토리는 인가 서버에 일차적으로 저장된 클라이언트 등록 정보 일부를 검색하는 기능을 제공한다.
- ClientRegistrationRepository의 디폴트 구현체는 InMemoryClientRegistrationRepository이다.
- 자동 설정을 하게 되면 ClientRegistrationRepository도 ApplicationContext 내에 @Bean 어노테이션을 달아 스프링 빈으로의 등록이 필요하므로 필요하다면 원하는 곳에서 의존성을 주입할 수 있다.
@Component
public class CustomClientRegistrationRepository {
@Bean
public ClientRegistrationRepository clientRegistrationRepository() {
return new InMemoryClientRegistrationRepository(this. keycloakClientRegistration());
}
private ClientRegistration keycloakClientRegistration() {
return ClientRegistration.withRegistrationId("keycloak")
.clientId("keycloak-client-id")
.clientSecret("keycloak-client-secret")
.clientAuthenticationMethod(ClientAuthenticationMethod.CLIENT_SECRET_BASIC)
.authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE)
.redirectUri("{baseUrl}/login/oauth2/code/{registrationId}")
.scope("openid", "profile", "email", "address", "phone")
.authorizationUri("http://localhost:8080/realms/oauth2")
.tokenUri("http://localhost:8080/realms/oauth2/token")
.userInfoUri("http://localhost:8080/realms/oauth2/userinfo")
.userNameAttributeName(IdTokenClaimNames.SUB)
.jwkSetUri("http://localhost:8080/realms/oauth2/certs")
.clientName("Keycloak")
.build();
}
}
📚 자동설정에 의한 초기화