FroMage / redpipe

Redpipe Web Framework
Apache License 2.0
70 stars 10 forks source link

keycloack roles #15

Open johnfg2610 opened 6 years ago

johnfg2610 commented 6 years ago

Hey, I have been testing out redpipe the last day or so and have set it up with keycloack is there any way to make it use keycloack roles with the RequiresPermissions annotation? maybe related to this error im receiving:

Mar 25, 2018 9:14:56 PM io.vertx.ext.auth.oauth2.impl.OAuth2TokenImpl
WARNING: Cannot decode token:
java.lang.RuntimeException: Not enough or too many segments
    at io.vertx.ext.jwt.JWT.decode(JWT.java:259)
    at io.vertx.ext.auth.oauth2.impl.OAuth2TokenImpl.decodeToken(OAuth2TokenImpl.java:102)
    at io.vertx.ext.auth.oauth2.impl.OAuth2TokenImpl.init(OAuth2TokenImpl.java:124)
    at io.vertx.ext.auth.oauth2.impl.OAuth2TokenImpl.<init>(OAuth2TokenImpl.java:83)
    at io.vertx.ext.auth.oauth2.impl.flow.AuthCodeImpl.lambda$getToken$0(AuthCodeImpl.java:81)
    at io.vertx.ext.auth.oauth2.impl.flow.AbstractOAuth2Flow.lambda$getToken$0(AbstractOAuth2Flow.java:135)
    at io.vertx.ext.auth.oauth2.impl.OAuth2API.lambda$null$1(OAuth2API.java:121)
    at io.vertx.core.http.impl.HttpClientResponseImpl$BodyHandler.notifyHandler(HttpClientResponseImpl.java:302)
    at io.vertx.core.http.impl.HttpClientResponseImpl.lambda$bodyHandler$0(HttpClientResponseImpl.java:192)
    at io.vertx.core.http.impl.HttpClientResponseImpl.handleEnd(HttpClientResponseImpl.java:256)
    at io.vertx.core.http.impl.Http1xClientConnection$StreamImpl.endResponse(Http1xClientConnection.java:376)
    at io.vertx.core.http.impl.Http1xClientConnection.handleResponseEnd(Http1xClientConnection.java:456)
    at io.vertx.core.http.impl.Http1xClientHandler.handleMessage(Http1xClientHandler.java:115)
    at io.vertx.core.http.impl.Http1xClientHandler.handleMessage(Http1xClientHandler.java:32)
    at io.vertx.core.net.impl.VertxHandler.lambda$channelRead$1(VertxHandler.java:146)
    at io.vertx.core.impl.ContextImpl.lambda$wrapTask$2(ContextImpl.java:337)
    at io.vertx.core.impl.ContextImpl.executeFromIO(ContextImpl.java:195)
    at io.vertx.core.net.impl.VertxHandler.channelRead(VertxHandler.java:144)
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362)
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348)
    at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:340)
    at io.netty.channel.CombinedChannelDuplexHandler$DelegatingChannelHandlerContext.fireChannelRead(CombinedChannelDuplexHandler.java:438)
    at io.netty.handler.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:310)
    at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:284)
    at io.netty.channel.CombinedChannelDuplexHandler.channelRead(CombinedChannelDuplexHandler.java:253)
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362)
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348)
    at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:340)
    at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1359)
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362)
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348)
    at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:935)
    at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:141)
    at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:645)
    at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:580)
    at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:497)
    at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:459)
    at io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:886)
    at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
    at java.lang.Thread.run(Thread.java:748)

Thanks, John

FroMage commented 6 years ago

Yes, this application shows how to use keycloak roles with the annotation: https://github.com/FroMage/redpipe/tree/master/redpipe-example-wiki-keycloak-jooq

Did you follow this example?

http://redpipe.net/#authentication also has info.

Also, my JWT for vertx 3.5.0 does not have the right line-info, so I assume you're running 3.5.1?

johnfg2610 commented 6 years ago

I followed http://redpipe.net/#authentication and yes I am running 3.5.1 is there anything else I need to do?

    override fun setupRoutes(router: Router) {
        //good solution to loading resources from the web root folder
        router.route("/webroot/*").handler(StaticHandler.create().setCachingEnabled(true))
        super.setupRoutes(router)
    }

    override fun setupAuthenticationRoutes(): AuthProvider {
        val keycloackConfig = AppGlobals.get().config.getJsonObject("keycloack")
        val authWeb = KeycloakAuth.create(AppGlobals.get().vertx, keycloackConfig)
        val authApi = KeycloakAuth.create(AppGlobals.get().vertx, OAuth2FlowType.PASSWORD, keycloackConfig)

        // FIXME: URL
        val authHandler = OAuth2AuthHandler.create(authWeb as OAuth2Auth, "http://localhost:9000/callback")
        val router = AppGlobals.get().router
        // FIXME: crazy!!
        val authProvider = AuthProvider.newInstance(authWeb.getDelegate())
        router.route().handler(UserSessionHandler.create(authProvider))

        authHandler.setupCallback(router.get("/callback"))

        val jwtAuth = JWTAuth.create(AppGlobals.get().vertx,
                JWTAuthOptions(
                        JWTOptions(
                                JsonObject().put("keyStore", AppGlobals.get().config.getJsonObject("keystore")))))

        AppGlobals.get().setGlobal(JWTAuth::class.java, jwtAuth)
        val jwtAuthHandler = JWTAuthHandler.create(jwtAuth, "/wiki/api/token")

        // FIXME: just use different routers
        router.route().handler { ctx ->
            if (!ctx.request().uri().startsWith("/wiki/api/"))
                authHandler.handle(ctx)
            else
                jwtAuthHandler.handle(ctx)
        }

        return AuthProvider.newInstance(authApi.delegate)
    }

this is all the code from the overriden server instance(its kotlin)

FroMage commented 6 years ago

So I tried with vertx 3.5.1 and it works here. This is with keycloack 3.3.0.CR2 and 3.3.0.Final. What version of keycloak did you try?

FroMage commented 6 years ago

Also, what does your conf/config.json look like?

johnfg2610 commented 6 years ago

i have keycloak 4.0.0.beta1(il try downgrading shortly it may be that) my config.json


{
  "scan": ["io.github.johnfg10"],
  "keycloack":{
    "realm": "jtube",
    "auth-server-url": "http://localhost:8081/auth",
    "ssl-required": "external",
    "resource": "jtube",
    "credentials": {
      "secret": "3******f-8e*a-*c1f-a*02-****f3ab78**"
    },
    "use-resource-role-mappings": true,
    "confidential-port": 0,
    "policy-enforcer": {}
  }
}
johnfg2610 commented 6 years ago

sorry it took a few days ive been a little bit busy but ive downgraded to 3.4.3-final that also doesnt work. i have just tested 3.3.0.final and il upload the settings i have on keycloak image

FroMage commented 6 years ago

So I have the following settings different:

Consent required: off Direct Access Grants Enabled: on Service Accounts Enabled: off Authorization enabled: off Valid redirect URIs: http://localhost:9000/callback/*

The rest are the same.

johnfg2610 commented 6 years ago

ive tried with the same settings and am still encountering the same errors