사용환경
• Keycloak 인증서버
• Keycloak 의 OIDC 인증을 사용하는 Springboot 서버 (keycloak-spring-security-adapter 사용)
• Springboot 서버의 API 를 제공하는 Swagger3 UI
• 모두 하나의 서버(도메인은 example.net 으로 지칭)에서 Keycloak(8280포트) 과 Swagger(8180포트) 는 도커 사용, Springboot(9080포트) 서버는 호스트에서 실행
목표
구현하고자 했던 목표는 Springboot 서버에서 Keycloak 인증이 필요한 API 를 Swagger 에서 API 를 호출 해보고자 하는것이다.
예를들면 "내 정보 조회" 라는 API 는 로그인을 하여야 내가 누군지 알 수 있다.
하지만 이 로그인은 다른 SSO 서버인 Keycloak 에서 제공하는 로그인이며,
이 API 를 Swagger 에서 호출하려면 Keycloak 로그인을 하여야 API 를 호출할 수 있다.
각각의 서버들에 대한 구현은 제외하고, 위 목표를 구현하는 방법에 대해서만 작성한다.
Keycloak
Keycloak 에서 OIDC 인증을 사용할 클라이언트를 생성해준다.
Keycloak 을 다른 서버에서 사용하기 위한 설정 또는 데이터는 아래와 같다.
• Clients > Settings > Access Type: confidential
• Clients > Settings > Valid Redirect URIs: http://example.net:8180/*
• Clients > Settings > Web Origins: http://example.net:8180
• Realm Settings > General > Endpoints > OpenID Endpoint Configuration
• Clients > Credentials > Secret
Valid Redirect URIs 는 로그인 이후 Redirect 할 페이지에 대한 URI 를 설정하며, 도메인과 더불어 와일드카드(*)를 함께 사용할 수 있다.
Web Origins 는 와일드카드 단독 사용 혹은 URI 를 정확하게 입력하여야 한다.
Swagger
docker-compose.yml 파일
version: '3.3'
services:
swagger-ui:
image: swaggerapi/swagger-ui:v3.43.0
ports:
- 8180:8080
volumes:
- /home/docker/docker-stack/swagger3/conf/:/home/swagger3/
environment:
SWAGGER_JSON: /home/swagger3/test_oas3.yaml
BASE_URL: /swagger-ui
OAUTH2_REDIRECT_URL: "http://example.net:8180/swagger-ui/oauth2-redirect.html"
deploy:
mode: replicated
replicas: 1
swagger-editor:
image: swaggerapi/swagger-editor:v3.15.6
ports:
- 8181:8080
environment:
BASE_URL: /swagger-editor
OAUTH2_REDIRECT_URL: "http://example.net:8181/swagger-editor/oauth2-redirect.html"
deploy:
mode: replicated
replicas: 1
test_oas3.yaml 파일 (인증 관련된 코드만 삽입)
openIdConnectUrl 에 Keycloak 의 OpenID Endpoint Configuration 의 url 을 입력하였다.
paths:
/auth/getUserInfo:
post:
tags:
- auth
summary: 사용자정보 조회
security:
- openId:
- admin
responses:
200:
components:
securitySchemes:
openId: # <--- Arbitrary name for the security scheme. Used to refer to it from elsewhere.
type: openIdConnect
openIdConnectUrl: http://example.net:8280/auth/realms/master/.well-known/openid-configuration
security:
- openId:
- admin
Springboot API 서버
의존성
implementation 'org.springframework.boot:spring-boot-starter-security'
implementation group: 'org.keycloak', name: 'keycloak-spring-security-adapter', version: '13.0.1'
Spring security 설정
WebMvcConfigurer 의 CORS 설정 외에도 스프링 시큐리티에 의한 CORS 설정도 추가로 필요하다.
@KeycloakConfiguration
public class SecurityConfig extends KeycloakWebSecurityConfigurerAdapter {
// 인증관리 객체에 소유권한 프로바이더 추가
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) {
// GrantedAuthoritesMapper 에서 오는 Role 을 Spring Security 가 인식할 수 있도록 Role Mapping 을 지원
KeycloakAuthenticationProvider keycloakAuthenticationProvider = keycloakAuthenticationProvider();
// SimpleAutorityMapper 는 "ROLE_" 을 삽입 및 대문자로 변환하는데 사용 (Spring Security Core 모듈의 일부)
keycloakAuthenticationProvider.setGrantedAuthoritiesMapper(new SimpleAuthorityMapper());
auth.authenticationProvider(keycloakAuthenticationProvider);
}
// 세션인증전략 생성
@Bean
@Override
protected SessionAuthenticationStrategy sessionAuthenticationStrategy() {
return new RegisterSessionAuthenticationStrategy(new SessionRegistryImpl());
}
// 키클락 설정 리졸버 생성
@Bean
public KeycloakConfigResolver keycloakConfigResolver() {
return new KeycloakConfigResolver() {
private KeycloakDeployment keycloakDeployment;
@Override
public KeycloakDeployment resolve(HttpFacade.Request facade) {
if (keycloakDeployment = null) {
return keycloakDeployment;
}
InputStream configInputStream = getClass().getResourceAsStream("/keycloak.json");
return KeycloakDeploymentBuilder.build(configInputStream);
}
};
}
// 시큐리티 설정
@Override
protected void configure(HttpSecurity http) throws Exception {
super.configure(http);
http
.cors() // spring security cors
.configurationSource(request ->
{
CorsConfiguration cors = new CorsConfiguration();
cors.setAllowedMethods(
Arrays.asList(HttpMethod.GET.name(), HttpMethod.POST.name()));
cors.applyPermitDefaultValues();
return cors;
});
}
}
keycloak.json
{"realm": "master", "auth-server-url": "http://example.net:8280/auth", "ssl-required": "external", "resource": "springboot-test-app", "credentials": { "secret": "해당 keycloak client 의 secret 키 입력" }, "confidential-port": 0}
'IT > 스프링부트' 카테고리의 다른 글
Forward, Redirect 간단하게 정리 (0) | 2021.07.15 |
---|---|
SpringSecurity 와 Keycloak 비교 (0) | 2021.05.11 |