简体   繁体   中英

Secure Spring Cloud Gateway with Keycloak

I'm new to both technologies, Spring Cloud and Keycloak.

I would like to have something like the architecture described in the spring blog post , just working with Keycloak instead of Cloud Foundry UAA. I started with it but couldn't adapt it to Keycloak successfully.

In pom.xml file of the security-gateway , I updated Spring Cloud version to Hoxton.SR1 and Spring Boot version to 2.2.4.RELEASE . I also modified application.yml file to this:

server:
  port: 8080

spring:
  #  autoconfigure:
  #     TODO: remove when fixed https://github.com/spring-projects/spring-security/issues/6314
  #    exclude: org.springframework.boot.actuate.autoconfigure.security.reactive.ReactiveManagementWebSecurityAutoConfiguration
  thymeleaf:
    cache: false
  security:
    oauth2:
      client:
        registration:
          proxy:
            provider: keycloak
            client-id: proxy
            client-secret: ce9db646-8fff-4652-83f3-8c77f48acb21
            authorization-grant-type: authorization_code
            client-authentication-method: public
            redirect-uri: "http://localhost:8080/"
#            scope: openid,profile,email,resource.read,offline_access
        provider:
          keycloak:
#            authorization-uri: http://localhost:8190/uaa/oauth/authorize
#            token-uri: http://uaa:8090/uaa/oauth/token
#            user-info-uri: http://uaa:8090/uaa/userinfo
            issuer-uri: http://localhost:8180/auth/realms/myrrealm
            user-name-attribute: preferred_username
#            jwk-set-uri: http://uaa:8090/uaa/token_keys

When I run the main class and try to open localhost:8080 by browser, I get this error:

Whitelabel Error Page

This application has no configured error view, so you are seeing this as a fallback.
Sun Feb 02 00:54:35 IRST 2020
[409eabdf] There was an unexpected error (type=Internal Server Error, status=500).
[not_allowed] Offline tokens not allowed for the user or client

And full stacktrace is this:

2020-02-02 00:54:35.736 ERROR 13228 --- [or-http-epoll-3] a.w.r.e.AbstractErrorWebExceptionHandler : [409eabdf]  500 Server Error for HTTP GET "/?state=jBRwSTkrRXZLv3aOTWBqrfQ9bf9w_tUWtmr2RrsJirI%3D&session_state=7ef178c2-f2b4-4085-83da-0b94c8b139f6&code=66bcf3e8-98ce-4c37-8d50-bc9fb88cda45.7ef178c2-f2b4-4085-83da-0b94c8b139f6.c42cb75f-32f2-4049-8be4-5e5483fadd3d"

org.springframework.security.oauth2.core.OAuth2AuthorizationException: [not_allowed] Offline tokens not allowed for the user or client
    at org.springframework.security.oauth2.core.web.reactive.function.OAuth2AccessTokenResponseBodyExtractor.oauth2AccessTokenResponse(OAuth2AccessTokenResponseBodyExtractor.java:93) ~[spring-security-oauth2-core-5.2.1.RELEASE.jar:5.2.1.RELEASE]
    Suppressed: reactor.core.publisher.FluxOnAssembly$OnAssemblyException: 
Error has been observed at the following site(s):
    |_ checkpoint ⇢ Body from POST http://localhost:8180/auth/realms/myrealm/protocol/openid-connect/token [DefaultClientResponse]
    |_ checkpoint ⇢ org.springframework.security.oauth2.client.web.server.OAuth2AuthorizationCodeGrantWebFilter [DefaultWebFilterChain]
    |_ checkpoint ⇢ org.springframework.security.oauth2.client.web.server.authentication.OAuth2LoginAuthenticationWebFilter [DefaultWebFilterChain]
    |_ checkpoint ⇢ org.springframework.security.oauth2.client.web.server.OAuth2AuthorizationRequestRedirectWebFilter [DefaultWebFilterChain]
    |_ checkpoint ⇢ org.springframework.security.oauth2.client.web.server.OAuth2AuthorizationRequestRedirectWebFilter [DefaultWebFilterChain]
    |_ checkpoint ⇢ org.springframework.security.web.server.context.ReactorContextWebFilter [DefaultWebFilterChain]
    |_ checkpoint ⇢ org.springframework.security.web.server.csrf.CsrfWebFilter [DefaultWebFilterChain]
    |_ checkpoint ⇢ org.springframework.security.web.server.header.HttpHeaderWriterWebFilter [DefaultWebFilterChain]
    |_ checkpoint ⇢ org.springframework.security.config.web.server.ServerHttpSecurity$ServerWebExchangeReactorContextWebFilter [DefaultWebFilterChain]
    |_ checkpoint ⇢ org.springframework.security.web.server.WebFilterChainProxy [DefaultWebFilterChain]
    |_ checkpoint ⇢ org.springframework.boot.actuate.metrics.web.reactive.server.MetricsWebFilter [DefaultWebFilterChain]
    |_ checkpoint ⇢ HTTP GET "/?state=jBRwSTkrRXZLv3aOTWBqrfQ9bf9w_tUWtmr2RrsJirI%3D&session_state=7ef178c2-f2b4-4085-83da-0b94c8b139f6&code=66bcf3e8-98ce-4c37-8d50-bc9fb88cda45.7ef178c2-f2b4-4085-83da-0b94c8b139f6.c42cb75f-32f2-4049-8be4-5e5483fadd3d" [ExceptionHandlingWebHandler]
Stack trace:
        at org.springframework.security.oauth2.core.web.reactive.function.OAuth2AccessTokenResponseBodyExtractor.oauth2AccessTokenResponse(OAuth2AccessTokenResponseBodyExtractor.java:93) ~[spring-security-oauth2-core-5.2.1.RELEASE.jar:5.2.1.RELEASE]
        at org.springframework.security.oauth2.core.web.reactive.function.OAuth2AccessTokenResponseBodyExtractor$$Lambda$1047/190026310.apply(Unknown Source) ~[na:na]
        at reactor.core.publisher.MonoFlatMap$FlatMapMain.onNext(MonoFlatMap.java:118) [reactor-core-3.3.2.RELEASE.jar:3.3.2.RELEASE]
        at reactor.core.publisher.FluxMapFuseable$MapFuseableSubscriber.onNext(FluxMapFuseable.java:121) [reactor-core-3.3.2.RELEASE.jar:3.3.2.RELEASE]
        at reactor.core.publisher.Operators$MonoSubscriber.complete(Operators.java:1637) [reactor-core-3.3.2.RELEASE.jar:3.3.2.RELEASE]
        at reactor.core.publisher.MonoFlatMap$FlatMapMain.onNext(MonoFlatMap.java:144) [reactor-core-3.3.2.RELEASE.jar:3.3.2.RELEASE]
        at reactor.core.publisher.FluxContextStart$ContextStartSubscriber.onNext(FluxContextStart.java:103) [reactor-core-3.3.2.RELEASE.jar:3.3.2.RELEASE]
        at reactor.core.publisher.FluxContextStart$ContextStartSubscriber.onNext(FluxContextStart.java:103) [reactor-core-3.3.2.RELEASE.jar:3.3.2.RELEASE]
        at reactor.core.publisher.FluxMapFuseable$MapFuseableConditionalSubscriber.onNext(FluxMapFuseable.java:287) [reactor-core-3.3.2.RELEASE.jar:3.3.2.RELEASE]
        at reactor.core.publisher.FluxFilterFuseable$FilterFuseableConditionalSubscriber.onNext(FluxFilterFuseable.java:330) [reactor-core-3.3.2.RELEASE.jar:3.3.2.RELEASE]
        at reactor.core.publisher.Operators$MonoSubscriber.complete(Operators.java:1637) [reactor-core-3.3.2.RELEASE.jar:3.3.2.RELEASE]
        at reactor.core.publisher.MonoCollect$CollectSubscriber.onComplete(MonoCollect.java:160) [reactor-core-3.3.2.RELEASE.jar:3.3.2.RELEASE]
        at reactor.core.publisher.FluxMap$MapSubscriber.onComplete(FluxMap.java:136) [reactor-core-3.3.2.RELEASE.jar:3.3.2.RELEASE]
        at reactor.core.publisher.FluxPeek$PeekSubscriber.onComplete(FluxPeek.java:252) [reactor-core-3.3.2.RELEASE.jar:3.3.2.RELEASE]
        at reactor.core.publisher.FluxPeek$PeekSubscriber.onComplete(FluxPeek.java:252) [reactor-core-3.3.2.RELEASE.jar:3.3.2.RELEASE]
        at reactor.core.publisher.FluxMap$MapSubscriber.onComplete(FluxMap.java:136) [reactor-core-3.3.2.RELEASE.jar:3.3.2.RELEASE]
        at reactor.netty.channel.FluxReceive.terminateReceiver(FluxReceive.java:419) [reactor-netty-0.9.4.RELEASE.jar:0.9.4.RELEASE]
        at reactor.netty.channel.FluxReceive.drainReceiver(FluxReceive.java:209) [reactor-netty-0.9.4.RELEASE.jar:0.9.4.RELEASE]
        at reactor.netty.channel.FluxReceive.onInboundComplete(FluxReceive.java:367) [reactor-netty-0.9.4.RELEASE.jar:0.9.4.RELEASE]
        at reactor.netty.channel.ChannelOperations.onInboundComplete(ChannelOperations.java:363) [reactor-netty-0.9.4.RELEASE.jar:0.9.4.RELEASE]
        at reactor.netty.channel.ChannelOperations.terminate(ChannelOperations.java:412) [reactor-netty-0.9.4.RELEASE.jar:0.9.4.RELEASE]
        at reactor.netty.http.client.HttpClientOperations.onInboundNext(HttpClientOperations.java:572) [reactor-netty-0.9.4.RELEASE.jar:0.9.4.RELEASE]
        at reactor.netty.channel.ChannelOperationsHandler.channelRead(ChannelOperationsHandler.java:90) [reactor-netty-0.9.4.RELEASE.jar:0.9.4.RELEASE]
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:377) [netty-transport-4.1.45.Final.jar:4.1.45.Final]
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:363) [netty-transport-4.1.45.Final.jar:4.1.45.Final]
        at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:355) [netty-transport-4.1.45.Final.jar:4.1.45.Final]
        at io.netty.handler.codec.MessageToMessageDecoder.channelRead(MessageToMessageDecoder.java:102) [netty-codec-4.1.45.Final.jar:4.1.45.Final]
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:377) [netty-transport-4.1.45.Final.jar:4.1.45.Final]
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:363) [netty-transport-4.1.45.Final.jar:4.1.45.Final]
        at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:355) [netty-transport-4.1.45.Final.jar:4.1.45.Final]
        at io.netty.channel.CombinedChannelDuplexHandler$DelegatingChannelHandlerContext.fireChannelRead(CombinedChannelDuplexHandler.java:436) [netty-transport-4.1.45.Final.jar:4.1.45.Final]
        at io.netty.handler.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:321) [netty-codec-4.1.45.Final.jar:4.1.45.Final]
        at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:295) [netty-codec-4.1.45.Final.jar:4.1.45.Final]
        at io.netty.channel.CombinedChannelDuplexHandler.channelRead(CombinedChannelDuplexHandler.java:251) [netty-transport-4.1.45.Final.jar:4.1.45.Final]
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:377) [netty-transport-4.1.45.Final.jar:4.1.45.Final]
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:363) [netty-transport-4.1.45.Final.jar:4.1.45.Final]
        at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:355) [netty-transport-4.1.45.Final.jar:4.1.45.Final]
        at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1410) [netty-transport-4.1.45.Final.jar:4.1.45.Final]
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:377) [netty-transport-4.1.45.Final.jar:4.1.45.Final]
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:363) [netty-transport-4.1.45.Final.jar:4.1.45.Final]
        at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:919) [netty-transport-4.1.45.Final.jar:4.1.45.Final]
        at io.netty.channel.epoll.AbstractEpollStreamChannel$EpollStreamUnsafe.epollInReady(AbstractEpollStreamChannel.java:792) [netty-transport-native-epoll-4.1.45.Final-linux-x86_64.jar:4.1.45.Final]
        at io.netty.channel.epoll.EpollEventLoop.processReady(EpollEventLoop.java:475) [netty-transport-native-epoll-4.1.45.Final-linux-x86_64.jar:4.1.45.Final]
        at io.netty.channel.epoll.EpollEventLoop.run(EpollEventLoop.java:378) [netty-transport-native-epoll-4.1.45.Final-linux-x86_64.jar:4.1.45.Final]
        at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:989) [netty-common-4.1.45.Final.jar:4.1.45.Final]
        at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74) [netty-common-4.1.45.Final.jar:4.1.45.Final]
        at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30) [netty-common-4.1.45.Final.jar:4.1.45.Final]
        at java.lang.Thread.run(Thread.java:745) [na:1.8.0_25]


How should I fix the problem?

Any help would be greatly appreciated!

根据这篇博文及其对应的github 项目,问题通过在 application.yml 中注释掉另外三行来解决: authorization-grant-typeclient-authentication-methodredirect-uri

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM