SpringCloudをベースにしたマイクロサービスインフラストラクチャを開発しています。 Keycloakでアプリケーションを保護したいのですが、ユーザーが認証されていれば基本的には正常に機能しています。
ユーザーが認証されていない場合、Keycloakは次のエラーをスローします。
Java.lang.ClassCastException: org.springframework.security.authentication.AnonymousAuthenticationToken cannot be cast to org.keycloak.adapters.springsecurity.token.KeycloakAuthenticationToken
at org.keycloak.adapters.springsecurity.facade.SimpleHttpFacade.getSecurityContext(SimpleHttpFacade.Java:63) ~[keycloak-spring-security-adapter-3.4.3.Final.jar:3.4.3.Final]
at org.keycloak.adapters.AuthenticatedActionsHandler.corsRequest(AuthenticatedActionsHandler.Java:102) ~[keycloak-adapter-core-3.4.3.Final.jar:3.4.3.Final]
at org.keycloak.adapters.AuthenticatedActionsHandler.handledRequest(AuthenticatedActionsHandler.Java:54) ~[keycloak-adapter-core-3.4.3.Final.jar:3.4.3.Final]
at org.keycloak.adapters.springsecurity.filter.KeycloakAuthenticatedActionsFilter.doFilter(KeycloakAuthenticatedActionsFilter.Java:78) ~[keycloak-spring-security-adapter-3.4.3.Final.jar:3.4.3.Final]
at org.Apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.Java:193) ~[Tomcat-embed-core-8.5.23.jar:8.5.23]
at org.Apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.Java:166) ~[Tomcat-embed-core-8.5.23.jar:8.5.23]
at org.springframework.boot.actuate.trace.WebRequestTraceFilter.doFilterInternal(WebRequestTraceFilter.Java:110) ~[spring-boot-actuator-1.5.9.RELEASE.jar:1.5.9.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.Java:107) ~[spring-web-4.3.13.RELEASE.jar:4.3.13.RELEASE]
at org.Apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.Java:193) ~[Tomcat-embed-core-8.5.23.jar:8.5.23]
at org.Apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.Java:166) ~[Tomcat-embed-core-8.5.23.jar:8.5.23]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.Java:317) ~[spring-security-web-4.2.3.RELEASE.jar:4.2.3.RELEASE]
at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.Java:127) ~[spring-security-web-4.2.3.RELEASE.jar:4.2.3.RELEASE]
at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.Java:91) ~[spring-security-web-4.2.3.RELEASE.jar:4.2.3.RELEASE]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.Java:331) ~[spring-security-web-4.2.3.RELEASE.jar:4.2.3.RELEASE]
at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.Java:114) ~[spring-security-web-4.2.3.RELEASE.jar:4.2.3.RELEASE]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.Java:331) ~[spring-security-web-4.2.3.RELEASE.jar:4.2.3.RELEASE]
at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.Java:137) ~[spring-security-web-4.2.3.RELEASE.jar:4.2.3.RELEASE]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.Java:331) ~[spring-security-web-4.2.3.RELEASE.jar:4.2.3.RELEASE]
at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.Java:111) ~[spring-security-web-4.2.3.RELEASE.jar:4.2.3.RELEASE]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.Java:331) ~[spring-security-web-4.2.3.RELEASE.jar:4.2.3.RELEASE]
at org.keycloak.adapters.springsecurity.filter.KeycloakSecurityContextRequestFilter.doFilter(KeycloakSecurityContextRequestFilter.Java:79) ~[keycloak-spring-security-adapter-3.4.3.Final.jar:3.4.3.Final]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.Java:331) ~[spring-security-web-4.2.3.RELEASE.jar:4.2.3.RELEASE]
at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.Java:170) ~[spring-security-web-4.2.3.RELEASE.jar:4.2.3.RELEASE]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.Java:331) ~[spring-security-web-4.2.3.RELEASE.jar:4.2.3.RELEASE]
at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.Java:63) ~[spring-security-web-4.2.3.RELEASE.jar:4.2.3.RELEASE]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.Java:331) ~[spring-security-web-4.2.3.RELEASE.jar:4.2.3.RELEASE]
at org.keycloak.adapters.springsecurity.filter.KeycloakAuthenticatedActionsFilter.doFilter(KeycloakAuthenticatedActionsFilter.Java:82) ~[keycloak-spring-security-adapter-3.4.3.Final.jar:3.4.3.Final]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.Java:331) ~[spring-security-web-4.2.3.RELEASE.jar:4.2.3.RELEASE]
at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.Java:200) ~[spring-security-web-4.2.3.RELEASE.jar:4.2.3.RELEASE]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.Java:331) ~[spring-security-web-4.2.3.RELEASE.jar:4.2.3.RELEASE]
at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.Java:116) ~[spring-security-web-4.2.3.RELEASE.jar:4.2.3.RELEASE]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.Java:331) ~[spring-security-web-4.2.3.RELEASE.jar:4.2.3.RELEASE]
at org.keycloak.adapters.springsecurity.filter.KeycloakPreAuthActionsFilter.doFilter(KeycloakPreAuthActionsFilter.Java:84) ~[keycloak-spring-security-adapter-3.4.3.Final.jar:3.4.3.Final]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.Java:331) ~[spring-security-web-4.2.3.RELEASE.jar:4.2.3.RELEASE]
at org.springframework.security.web.csrf.CsrfFilter.doFilterInternal(CsrfFilter.Java:100) ~[spring-security-web-4.2.3.RELEASE.jar:4.2.3.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.Java:107) ~[spring-web-4.3.13.RELEASE.jar:4.3.13.RELEASE]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.Java:331) ~[spring-security-web-4.2.3.RELEASE.jar:4.2.3.RELEASE]
at org.springframework.web.filter.CorsFilter.doFilterInternal(CorsFilter.Java:96) ~[spring-web-4.3.13.RELEASE.jar:4.3.13.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.Java:107) ~[spring-web-4.3.13.RELEASE.jar:4.3.13.RELEASE]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.Java:331) ~[spring-security-web-4.2.3.RELEASE.jar:4.2.3.RELEASE]
at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.Java:64) ~[spring-security-web-4.2.3.RELEASE.jar:4.2.3.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.Java:107) ~[spring-web-4.3.13.RELEASE.jar:4.3.13.RELEASE]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.Java:331) ~[spring-security-web-4.2.3.RELEASE.jar:4.2.3.RELEASE]
at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.Java:105) ~[spring-security-web-4.2.3.RELEASE.jar:4.2.3.RELEASE]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.Java:331) ~[spring-security-web-4.2.3.RELEASE.jar:4.2.3.RELEASE]
at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.Java:56) ~[spring-security-web-4.2.3.RELEASE.jar:4.2.3.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.Java:107) ~[spring-web-4.3.13.RELEASE.jar:4.3.13.RELEASE]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.Java:331) ~[spring-security-web-4.2.3.RELEASE.jar:4.2.3.RELEASE]
at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.Java:214) ~[spring-security-web-4.2.3.RELEASE.jar:4.2.3.RELEASE]
at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.Java:177) ~[spring-security-web-4.2.3.RELEASE.jar:4.2.3.RELEASE]
at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.Java:347) ~[spring-web-4.3.13.RELEASE.jar:4.3.13.RELEASE]
at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.Java:263) ~[spring-web-4.3.13.RELEASE.jar:4.3.13.RELEASE]
at org.Apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.Java:193) ~[Tomcat-embed-core-8.5.23.jar:8.5.23]
at org.Apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.Java:166) ~[Tomcat-embed-core-8.5.23.jar:8.5.23]
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.Java:197) ~[spring-web-4.3.13.RELEASE.jar:4.3.13.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.Java:107) ~[spring-web-4.3.13.RELEASE.jar:4.3.13.RELEASE]
at org.Apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.Java:193) ~[Tomcat-embed-core-8.5.23.jar:8.5.23]
at org.Apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.Java:166) ~[Tomcat-embed-core-8.5.23.jar:8.5.23]
at org.springframework.boot.actuate.autoconfigure.MetricsFilter.doFilterInternal(MetricsFilter.Java:106) ~[spring-boot-actuator-1.5.9.RELEASE.jar:1.5.9.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.Java:107) ~[spring-web-4.3.13.RELEASE.jar:4.3.13.RELEASE]
at org.Apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.Java:193) ~[Tomcat-embed-core-8.5.23.jar:8.5.23]
at org.Apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.Java:166) ~[Tomcat-embed-core-8.5.23.jar:8.5.23]
at org.Apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.Java:199) ~[Tomcat-embed-core-8.5.23.jar:8.5.23]
at org.Apache.catalina.core.StandardContextValve.invoke(StandardContextValve.Java:96) [Tomcat-embed-core-8.5.23.jar:8.5.23]
at org.keycloak.adapters.Tomcat.AbstractAuthenticatedActionsValve.invoke(AbstractAuthenticatedActionsValve.Java:67) [spring-boot-container-bundle-3.4.3.Final.jar:3.4.3.Final]
at org.Apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.Java:595) [Tomcat-embed-core-8.5.23.jar:8.5.23]
at org.keycloak.adapters.Tomcat.AbstractKeycloakAuthenticatorValve.invoke(AbstractKeycloakAuthenticatorValve.Java:181) [spring-boot-container-bundle-3.4.3.Final.jar:3.4.3.Final]
at org.Apache.catalina.core.StandardHostValve.invoke(StandardHostValve.Java:140) [Tomcat-embed-core-8.5.23.jar:8.5.23]
at org.Apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.Java:81) [Tomcat-embed-core-8.5.23.jar:8.5.23]
at org.Apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.Java:87) [Tomcat-embed-core-8.5.23.jar:8.5.23]
at org.Apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.Java:342) [Tomcat-embed-core-8.5.23.jar:8.5.23]
at org.Apache.coyote.http11.Http11Processor.service(Http11Processor.Java:803) [Tomcat-embed-core-8.5.23.jar:8.5.23]
at org.Apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.Java:66) [Tomcat-embed-core-8.5.23.jar:8.5.23]
at org.Apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.Java:868) [Tomcat-embed-core-8.5.23.jar:8.5.23]
at org.Apache.Tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.Java:1459) [Tomcat-embed-core-8.5.23.jar:8.5.23]
at org.Apache.Tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.Java:49) [Tomcat-embed-core-8.5.23.jar:8.5.23]
at Java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source) [na:1.8.0_144]
at Java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source) [na:1.8.0_144]
at org.Apache.Tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.Java:61) [Tomcat-embed-core-8.5.23.jar:8.5.23]
at Java.lang.Thread.run(Unknown Source) [na:1.8.0_144]
セキュリティ設定は次のようになります。
@KeycloakConfiguration
public class SecurityConfig extends KeycloakWebSecurityConfigurerAdapter
{
private final KeycloakClientRequestFactory keycloakClientRequestFactory;
public SecurityConfig(KeycloakClientRequestFactory keycloakClientRequestFactory)
{
this.keycloakClientRequestFactory = keycloakClientRequestFactory;
}
/**
* define the actual constraints of the app.
* @param http
* @throws Exception
*/
@Override
protected void configure(HttpSecurity http) throws Exception
{
super.configure(http);
http
.cors()
.and()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.sessionAuthenticationStrategy(sessionAuthenticationStrategy())
.and()
.authorizeRequests()
.antMatchers("/*").hasRole("user")
.anyRequest().permitAll();
}
/**
* define the session auth strategy so that no session is created
*
* @return concrete implementation of session authentication strategy
*/
@Bean
@Override
protected SessionAuthenticationStrategy sessionAuthenticationStrategy()
{
return new NullAuthenticatedSessionStrategy();
}
/**
* registers the Keycloakauthenticationprovider in spring context and sets its
* mapping strategy for roles/authorities (mapping to spring seccurities'
* default ROLE_... for authorities ).
*
* @param auth
* SecurityBuilder to build authentications and add details like
* authproviders etc.
* @throws Exception
*/
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception
{
KeycloakAuthenticationProvider keyCloakAuthProvider = keycloakAuthenticationProvider();
keyCloakAuthProvider.setGrantedAuthoritiesMapper(new SimpleAuthorityMapper());
auth.authenticationProvider(keyCloakAuthProvider);
}
/**
* Sets keycloaks config resolver to use springs application.properties
* instead of keycloak.json (which is standard)
*
* @return
*/
@Bean
public KeycloakConfigResolver KeyCloakConfigResolver()
{
return new KeycloakSpringBootConfigResolver();
}
/**
* Spring Boot attempts to eagerly register filter beans with the web
* application context. Therefore, when running the Keycloak Spring Security
* adapter in a Spring Boot environment, it may be necessary to add two
* FilterRegistrationBeans to your security configuration to prevent the
* Keycloak filters from being registered twice.
*
* @param filter
* @return
*/
@Bean
public FilterRegistrationBean keycloakAuthenticationProcessingFilterRegistrationBean(
KeycloakAuthenticationProcessingFilter filter)
{
FilterRegistrationBean registrationBean = new FilterRegistrationBean(filter);
registrationBean.setEnabled(false);
return registrationBean;
}
/**
* Spring Boot attempts to eagerly register filter beans with the web
* application context. Therefore, when running the Keycloak Spring Security
* adapter in a Spring Boot environment, it may be necessary to add two
* FilterRegistrationBeans to your security configuration to prevent the
* Keycloak filters from being registered twice.
*
* @param filter
* @return
*/
@Bean
public FilterRegistrationBean keycloakPreAuthActionsFilterRegistrationBean(KeycloakPreAuthActionsFilter filter)
{
FilterRegistrationBean registrationBean = new FilterRegistrationBean(filter);
registrationBean.setEnabled(false);
return registrationBean;
}
}
どんな提案でも大いに感謝されるでしょう。
よろしくブラッキー
HttpSecurity httpに、.anonymous().disable()
のようなHttpSecurityを持つようにhttp.anonymous().disable()
を追加します。
私も同じ問題を抱えてる。
Keycloakクライアントをbearer-onlyに変更しても、問題は解決しませんでした。
そこにある問題は、パブリックエンドポイントです。
@Override
protected void configure( HttpSecurity http ) throws Exception {
super.configure( http );
http
.csrf().disable()
.sessionManagement()
.sessionCreationPolicy( SessionCreationPolicy.STATELESS )
.and()
.requestMatchers()
.and()
.authorizeRequests()
.antMatchers( "/tenants**" ).permitAll() // <- public endpoint
.anyRequest()
.authenticated();
}
これらのエンドポイントの場合、Spring Securityは、ダミーユーザー「anonymousUser」を使用して匿名認証を作成します。この認証は、KeycloakAuthenticationTokenにキャストできないAnonymousAuthenticationTokenのインスタンスです。
angular appのように、認証されたクライアントからリクエストを行おうとすると、認証ヘッダーで送信されたトークンを介して認証を解決できるため、機能します。これが理由です。ベアラのみのアプローチは同じ場合に機能します。
angular側で認証するための正しいレルムを取得するようにバックエンドにリクエストしたい。その瞬間、送信する認証トークンがないため、SpringSecurityが作成します。匿名認証。
例外は、keycloak.cors = trueの場合にのみスローされます。
この問題は、SimpleHttpFacade.classのメソッドgetSecurityContext()がメソッドcorsRequest()によってクラスAuthenticatedActionsHandler.classで呼び出されたときに発生します。
誰かが実用的な解決策を持っていますか?
宜しくお願いします
次のように、KeycloakのSpring Boot 2
依存関係を使用します。
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-spring-boot-2-starter</artifactId>
</dependency>
!アーティファクトIDの-2-
に注意してください。
Spring Bootの親は次のとおりです。
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.3.RELEASE</version>
<relativePath/>
</parent>
Keycloakの依存関係は次のとおりです。
<properties>
<keycloak.version>4.0.0.Final</keycloak.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.keycloak.bom</groupId>
<artifactId>keycloak-adapter-bom</artifactId>
<version>${keycloak.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
今日、これとまったく同じエラーに遭遇しました。 keycloak http.AuthorizeRequestをpermitAll()からauthenticated()にanyRequest()に交換するだけで解決しました。
pom.xml(未編集)
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.1.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
...
...
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.keycloak.bom</groupId>
<artifactId>keycloak-adapter-bom</artifactId>
<version>4.1.0.Final</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
KeycloakSecurityConfig.Java(OLD)
/**
* We require the user to be logged in for every single request
*/
@Override
protected void configure(HttpSecurity http) throws Exception {
super.configure(http);
http.authorizeRequests()
.antMatchers("/entry/sub/*").hasRole("roleA")
.anyRequest().permitAll();
}
KeycloakSecurityConfig.Java(NEW)
/**
* We require the user to be logged in for every single request
*/
@Override
protected void configure(HttpSecurity http) throws Exception {
super.configure(http);
http.authorizeRequests()
.antMatchers("/entry/sub/*").hasRole("roleA")
.anyRequest().authenticated();
}
スターターとアダプターにバージョン3.3.0.Final
を使用すると、うまくいきます。バージョンを3.4.3.Final
に変更すると、同じ例外が発生します。
Keycloakサーバー3.4.3(スタンドアロン)を実行しています...
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-spring-security-adapter</artifactId>
<version>3.3.0.Final</version>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-spring-boot-starter</artifactId>
<version>3.3.0.Final</version>
</dependency>
依存関係の現在のバージョンを使用するための解決策を知っている人はいますか?
トピックスターターと同様のエラーが発生しましたが、KeyCloakではなく社内認証トークンに関連しています。しかし、この質問は最初にGoogleで出てきたので、ここで答えます。
次のようなエントリを置き換えることで問題を解決しました。
<intercept-url pattern="^/login($|\?.*)" access="permitAll"/>
次のような行を含む春のセキュリティXML構成で:
<http security="none" pattern="/login" />
そのため、Springはそのようなリクエストに対して匿名ユーザートークンを作成しません。
マイクロサービスアーキテクチャでも同じ問題が発生しました。これによると this Stian Thorgersenからの回答すべてのReSTサービスは、ベアラのみである必要があります。したがって、トークンを受け入れる必要がありますが、ログインページへのリダイレクトは実行しないでください。
そのため、サービスからUIコンポーネントを抽出し、別のNGINXインスタンスで提供しました。 UIは、Keycloakログインページへのリダイレクトを実行し、セキュリティで保護されたサービスへの追加のGET/POST /その他の要求ごとにトークンを追加します。サービスとKeycloakの両方の構成で、すべてのReST-Servicesをkeycloak.bearer-only=true
に変更しました。今では魅力のように機能します。
これがお役に立てば幸いです。
フレディ
開発者はAPIゲートウェイにログインして、そこから直接サービスフォームを呼び出す必要があります。基本的なZuulFilter
を拡張するフィルターを追加することで、これを最終的に達成しました。
public class KeycloakAuthorizationFilter extends ZuulFilter
{
private static final String AUTHORIZATION_HEADER = "Authorization";
private static final String BEARER_TOKEN_TYPE = "Bearer";
private static Logger log = LoggerFactory.getLogger(KeycloakAuthorizationFilter.class);
@Override
public Object run()
{
log.info("Adding authenticaton header...");
RequestContext ctx = RequestContext.getCurrentContext();
if (ctx.getZuulRequestHeaders().containsKey(AUTHORIZATION_HEADER)) return null;
KeycloakAuthenticationToken authentication = (KeycloakAuthenticationToken) SecurityContextHolder.getContext()
.getAuthentication();
if(authentication == null)
{
log.error("Could not load authenticaton from security context!");
}
else if(authentication.isAuthenticated() == false)
{
log.error("Not authenticated!");
}
else
{
Object principal = authentication.getPrincipal();
if(principal != null && principal instanceof KeycloakPrincipal)
{
@SuppressWarnings("unchecked")
KeycloakPrincipal<KeycloakSecurityContext> keycloakPrincipal = (KeycloakPrincipal<KeycloakSecurityContext>) authentication
.getPrincipal();
log.info(String.format("Constructing Header %s for Token %s", AUTHORIZATION_HEADER, BEARER_TOKEN_TYPE));
ctx.addZuulRequestHeader(AUTHORIZATION_HEADER, String.format("%s %s", BEARER_TOKEN_TYPE, keycloakPrincipal.getKeycloakSecurityContext().getTokenString()));
}
}
return null;
}
@Override
public boolean shouldFilter()
{
return true;
}
@Override
public int filterOrder()
{
return 0;
}
@Override
public String filterType()
{
return "pre";
}
}
これは素晴らしい働きをしていて、より多くの柔軟性を提供します。