[keycloak-user] Keycloak adapter with policies returns bad request

Richard van Duijn rjvduijn at gmail.com
Thu Dec 8 14:46:08 EST 2016


Pedro,
I've imported the json file myself and I was able to fetch the AT with
postman and things work now. The only difference I see in the server
configuration is that I had confired the backend-client with Access-Type
'Bearer-only', which (after the import) is now 'Confidential'..

In my perception i had to configure the backend-client with a bearer-only
access-type as it does do any logins just as the 'bearer-only:true' flag in
the adapter config json.
Am I mistaken here?
Well at least I can continue now. but still this seems a bit odd to me.
Thank you again for your great help! It is much appreciated!
/Richard

Op do 8 dec. 2016 om 13:49 schreef Richard van Duijn <rjvduijn at gmail.com>:

> You've got me confused as well.. haha
>
> No I'm not reaching the lines using the policyEnforcer. The error occurs
> earlier in the process.
>
> Could you perhaps explain what you send in the postman request.
> What is put in it the request is the following:
>
>
> *requestHeaders.put("Authorization",
> BasicAuthHelper.createHeader(Configuration.this.clientId, secret));*
> with the clientId being: *backend-client* and the secret being:
> *6ce718ad-2ab1-42ff-bf01-35a03eab3aee*
> resulting in the header: *Authorization : Basic
> YmFja2VuZC1jbGllbnQ6NmNlNzE4YWQtMmFiMS00MmZmLWJmMDEtMzVhMDNlYWIzYWVl*
>
> Other than that I do not have any clues what is wrong.
>
> The AT request is generated during startup of my backend server. So I do
> not yet have any frontend rest calls containing a bearerToken comming in.
> My assumption is that I can initialize the keycloakDeployment once for my
> entire application and then use it for each call comming in. Am I correct?
> My guess now is that this assumption is wrong.
>
> /Richard
>
>
> Op do 8 dec. 2016 om 13:05 schreef Pedro Igor <psilva at redhat.com>:
>
> On 12/8/2016 7:06:44 AM, Richard van Duijn <rjvduijn at gmail.com> wrote:
> Hi Pedro,
> Thank you for the reply.
>
> Fist I'll answer your questions, then I'll clarify my setup a bit more.
> Please find attached my realm config file as well.
>
>
>    - The realm name was a typo. In the meantime I've reconfigured my
>    realm to ensure the '.' char was not messing up. Turned out not to be the
>    case.
>    - I'm not able to retrieve an AT from keycloak for the backend-client
>    (which is set to bearer-only). With the given Postman request I just get
>    the 400 bad request error and accompanying message.
>
> *Pedro Igor:* I was able to get an AT after importing your realm and
> sending the same postman request. Now I'm confused :) The client is
> backend-client, correct ?
>
>
>    - I've followed the getting started guid up to securing the jboss
>    servlet. I've stopped there as I wanted to use a keycloak distribution in
>    combination with a PlayFramework application (for which there is no adapter
>    available yet).
>
> I've followed the steps from this
> <http://bandrzejczak.com/blog/2015/11/22/single-sign-on-with-keycloak-in-a-sigle-page-application-part-1-slash-2-angular-dot-js/> post
> to get the bearerToken approach working. Using the
> *AdapterRSATokenVerifier* class I was able to verify the bearerToken
> received from the javascript frontend. What I basically have is a filter
> that intercepts the frontend requests, picks up the bearerToken and checks
> it's validity. If valid the resource is accessible otherwise the user
> receives an error.
>
>
> The next step was to include policies in the setup. Setting up the adapter
> for the playFramework was a bit difficult as there is no real documentation
> on that subject, only example implementations like the ones for spring
> security and jetty. But before getting to the complex logic I've added the
> policy-enforcer: {} line in the keycloak.json config file for the
> backend-client. This json is then loaded and used in
> *KeycloakDeploymentBuilder.build(keycloakConfig)*. This is the point
> where it fails, as the config contains the policy-enforcer line, the
> PolicyEnforcer class is initialized, which in turn attempts to retrieve the
> AT from keycloak.
>
> Is there some flaw in my reasoning?
>
>    1. The javascript frontend authenticates itself using the keycloak.js
>    adapter. It adds the accessToken to the Authorization header for the
>    rest-client to pickup
>    2. The rest client (my backend-client) verifies the bearerToken using
>    the AdapterRSATokenVerifier
>    3. Then the rest client checks the authorization using the folliwing
>    lines of code:
>
>
> *final PolicyEnforcer policyEnforcer =
> keycloakDeployment.getPolicyEnforcer();BearerTokenPolicyEnforcer
> bearerTokenPolicyEnforcer = new BearerTokenPolicyEnforcer(policyEnforcer);*
> *final AuthorizationContext authorizationContext =
> bearerTokenPolicyEnforcer.authorize(facade);*
>
> *Pedro Igor:* It looks correct. Although it seems you are not even
> reaching the line above where permissions are actually enforced. Besides,
> make sure you have all bearer token validations in place based on other
> adapters we have.
>
> You are almost there. You just need to figure out why you can't obtain an
> AT from the server even if using postman, curl, etc. I think that if you
> solve this, you will get everything working (or hit some new issue after
> this one :)).
>
>
> Hope this clarifies it a bit. I've attached my realm configuration json
> file. By the way I'm using keycloak 2.4.0-Final.
> Many many thanks for your help!
>
> If this approach is valid I'm hapy to contribute my code to the community
> for others to work with.
> /Richard
>
> Op do 8 dec. 2016 om 01:13 schreef Pedro Igor <psilva at redhat.com>:
>
> Hi Richard,
>
> In your first message, it seems the token endpoint is
> http://127.0.0.1:8080/auth/realms/local.development/protocol/openid-connect/token.Here
>  you are using a realm "local.development".
>
> In your last message with the postman request, you are using a token
> endpoint like this /auth/realms/development/protocol/openid-connect/token.
> Where the realm is "development", the same you have used in keycloak.json.
>
> Would that be a misconfiguration or just a typo ?
>
> Besides, what happens when you send that postman request to the server ?
> Are you able to get a AT ?
>
> This is pretty much what the enforcer does during initialization, obtain a
> AT before querying the Protection API for protected resources. And is what
> your stack trace shows.
>
> If you are not able to obtain a token using the postman request, it
> probably means you have something wrong with your realm/client
> configuration on the server.
>
> Last question, are you able to run any of our authorization examples ? Or
> even successfully follow our Getting Started guide ?
>
> Thanks.
> Pedro Igor
>
> On 12/7/2016 12:05:10 PM, Richard van Duijn <rjvduijn at gmail.com> wrote:
> Forgot to include the postman request.. here it is:
>
> POST /auth/realms/development/protocol/openid-connect/token HTTP/1.1
> Host: 127.0.0.1:8080
> Authorization: Basic
> YmFja2VuZC1jbGllbnQ6NmNlNzE4YWQtMmFiMS00MmZmLWJmMDEtMzVhMDNlYWIzYWVl
> Cache-Control: no-cache
> Content-Type: application/x-www-form-urlencoded
>
> grant_type=client_credentials
>
> /Richard
>
> Op wo 7 dec. 2016 om 15:00 schreef Richard van Duijn <rjvduijn at gmail.com>:
>
> Somehow I do not get any logs in keycloak server.log. I've attempted to
> change the loglevel in standalone.xml to TRACE, but to no avail. Maybe you
> can give me a pointer to which logger I should change to see the correct
> logs show up.
>
> Besides that I've done some debugging using Postman as well. Using the
> following request I get the message:
> {
>     "error": "invalid_client",
>     "error_description": "Bearer-only not allowed"
> }
>
> This is weird to me as the keycloak.json file states that I am connecting
> to a bearer-only client.
>
> Hope this helps to clarify it for you.
> My keycloak.json configuration file looks like this:
>
> {
>   "realm": "development",
>   "bearer-only": true,
>   "auth-server-url": "http://127.0.0.1:8080/auth",
>   "ssl-required": "external",
>   "resource": "backend-client",
>   "use-resource-role-mappings": true,
>   "credentials": {
>     "secret": "SECRETHERE"
>   },
>   "policy-enforcer": {}
> }
>
> Hope this helps to clarify some of your questions.
> /Richard
>
> Op wo 7 dec. 2016 om 12:47 schreef Pedro Igor <psilva at redhat.com>:
>
> Do you get anything in server logs ? It may be related with invalid client
> credentials.
>
> On 12/6/2016 12:41:38 PM, Richard van Duijn <rjvduijn at gmail.com> wrote:
> I'm creating a POC application using playframework and angular. The
> frontend will be protected using the keycloak javascript adapter and the
> backend rest services will be a bearer-only application.
>
> Without the policies turned on in the keycloak.json everything goes well.
> But when I turn the policies by adding "policy-enforcer": { } on for the
> rest services, I get an 400 Bad Request response from the Keycloak server
> during initialization.
> After some debugging I noticed it had to do with the initialization of the
> PolicyEnforcer which attempts to call the following server keycloak
> endpoint:
>
> http://127.0.0.1:8080/auth/realms/local.development/protocol/openid-connect/token
>
> Below you will find the stacktrace and request and response objects.
> Hope someone can point me in the right direction. For instance how to
> configure keycloak logging to get some more details on what the reason for
> the 400 bad request is.
> Many many thanks!
> /Richard
>
>
>
> *Stacktrace*:
>
> at
> org.keycloak.authorization.client.util.HttpMethod.execute(HttpMethod.java:92)
>
> at
> org.keycloak.authorization.client.util.HttpMethodResponse$2.execute(HttpMethodResponse.java:48)
>
> at
> org.keycloak.authorization.client.AuthzClient.obtainAccessToken(AuthzClient.java:112)
>
> at
> org.keycloak.authorization.client.AuthzClient.protection(AuthzClient.java:91)
>
> at
>
> org.keycloak.adapters.authorization.PolicyEnforcer.(PolicyEnforcer.java:57)
>
>
> at
> org.keycloak.adapters.KeycloakDeploymentBuilder.internalBuild(KeycloakDeploymentBuilder.java:126)
>
> at
> org.keycloak.adapters.KeycloakDeploymentBuilder.build(KeycloakDeploymentBuilder.java:135)
>
> at
> security.KeycloakSecurityModule.configure(KeycloakSecurityModule.java:53)
> at com.google.inject.AbstractModule.configure(AbstractModule.java:62)
> ... many google guice calls ...
> at
> play.core.server.DevServerStart$$anonfun$mainDev$1$$anon$1$$anonfun$get$1.apply(DevServerStart.scala:129)
>
> at
> play.core.server.DevServerStart$$anonfun$mainDev$1$$anon$1$$anonfun$get$1.apply(DevServerStart.scala:121)
>
>
>
> *Request object*:
>
> builder = {RequestBuilder at 12557}
> method = "POST"
> charset = {UTF_8 at 12563} "UTF-8"
> version = null
> uri = {URI at 12564} "
>
> http://127.0.0.1:8080/auth/realms/local.development/protocol/openid-connect/token
> "
> headergroup = {HeaderGroup at 12565} "[Authorization: Basic
> YmFja2VuZC1jbGllbnQ6NmNlNzE4YWQtMmFiMS00MmZmLWJmMDEtMzVhMDNlYWIzYWVl]"
> entity = null
> parameters = {LinkedList at 12566} size = 1
> 0 = {BasicNameValuePair at 12576} "grant_type=client_credentials"
> config = null
>
> *Response object*:
>
> HTTP/1.1 400 Bad Request [Connection: keep-alive, X-Powered-By:
> Undertow/1,
> Server: WildFly/10, Content-Type: application/json, Content-Length: 72,
> Date: Tue, 06 Dec 2016 12:24:28 GMT]
> org.apache.http.conn.BasicManagedEntity at 1f8d1780
> response = {$Proxy16 at 12554} "HTTP/1.1 400 Bad Request [Connection:
> keep-alive, X-Powered-By: Undertow/1, Server: WildFly/10, Content-Type:
> application/json, Content-Length: 72, Date: Tue, 06 Dec 2016 12:24:28 GMT]
> org.apache.http.conn.BasicManagedEntity at 1f8d1780"
> h = {CloseableHttpResponseProxy at 12583}
> original = {BasicHttpResponse at 12584} "HTTP/1.1 400 Bad Request
> [Connection: keep-alive, X-Powered-By: Undertow/1, Server: WildFly/10,
> Content-Type: application/json, Content-Length: 72, Date: Tue, 06 Dec 2016
> 12:24:28 GMT] org.apache.http.conn.BasicManagedEntity at 1f8d1780"
> statusline = {BasicStatusLine at 12556} "HTTP/1.1 400 Bad Request"
> ver = {HttpVersion at 12586} "HTTP/1.1"
> code = 400
> reasonPhrase = "Bad Request"
> entity = {BasicManagedEntity at 12555}
> reasonCatalog = {EnglishReasonPhraseCatalog at 12588}
> locale = {Locale at 12589} "en_US"
> headergroup = {HeaderGroup at 12590} "[Connection: keep-alive,
> X-Powered-By: Undertow/1, Server: WildFly/10, Content-Type:
> application/json, Content-Length: 72, Date: Tue, 06 Dec 2016 12:24:28
> GMT]"
> params = {ClientParamsStack at 12591}
>
> _______________________________________________
> keycloak-user mailing list
> keycloak-user at lists.jboss.org
> https://lists.jboss.org/mailman/listinfo/keycloak-user
>
>


More information about the keycloak-user mailing list