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

Richard van Duijn rjvduijn at gmail.com
Thu Dec 8 07:49:22 EST 2016


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