[keycloak-user] Restrict access from web app client
Pablo Fernandez
pablo.fernandez at cscs.ch
Fri Aug 18 11:32:35 EDT 2017
Dear Pedro,
Answers inline:
On 18/08/17 14:48, Pedro Igor Silva wrote:
> Hi Pablo,
>
> From your first e-mail, you posted the following policy:
>
> ---
> // by default, grants any permission associated with this policy
> //$evaluation.grant();
> var context = $evaluation.getContext();
> var contextAttributes = context.getAttributes();
> if (contextAttributes.containsValue('kc.client.id
> <http://kc.client.id/>', 'simplewebapp')) {
> $evaluation.deny();
> }
> $evaluation.grant();
> ---
>
> At the end of the script you are granting access, no matter what. You
> should try to change your code to avoid calling $evaluation.grant()
> after calling $evaluation.deny().
I just tried to put the grant() call inside an else (if condition then
deny else grant), but with the same result: the policy always returns
PERMIT (I just discovered the Evaluate tab). In fact, when I see the
authorization data (in the eval tab again) I don't see the kc.client.id
context attributes... but that's maybe a defect of the evaluation?
This is the info I get from the auth data, the only reference to
simplewebapp (client 1) is in resource_access:
{
"exp": 0,
"nbf": 0,
"iat": 0,
"iss": "https://myidp.domain.country:8443/auth/realms/keystonerealm",
"aud": "5e91cb22-991c-4874-b8fe-8add2d48b463",
"sub": "daf782c3-24d7-41fa-8bf1-4ace50b218c9",
"azp": "5e91cb22-991c-4874-b8fe-8add2d48b463",
"auth_time": 0,
"realm_access": {
"roles": [
"manage-account",
"realm-admin",
"offline_access",
"uma_authorization",
"view-profile"
]
},
"resource_access": {
"simplewebapp": {
"roles": []
},
"keystone": {
"roles": []
}
},
"authorization": {
"permissions": []
},
"LDAP_ENTRY_DN": [
"uid=pablof,ou=group,dc=aa,dc=bb"
],
"uidNumber": [
"21471"
],
"name": "Pablo ",
"preferred_username": "pablof",
"given_name": "Pablo",
"createTimestamp": [
"20170630074958Z"
],
"modifyTimestamp": [
"20170630074958Z"
],
"LDAP_ID": [
"pablof"
]
}
But then again I could not find a way to create a policy (for client 2)
based on resources from another client.
Something that puzzles me is that, even if I make enough conditions to
make my policy issue DENY, I can still log in with client 1 into client
2. Is there anything else I have to do to make the login fail?
>
> You don't really need to use a JS policy for such condition. Have you
> tried used the "Client Policy" ?
Yes, this is one of the things that I tried... but oddly enough, I
always get the same answer (DENY if set to Possitive logic, PERMIT if
set to Negative) regardless of the client 1 that I am using to access my
client 2.
>
> Could you provide more details about the application you are
> protecting ? What is the adapter you are using ? I think we have some
> tests that are doing pretty much the same thing you are looking for [1].
What do you mean by adapter in the application to protect? If what you
mean is how does client 2 accept/reject tokens, it's an Apache app (it's
actually OpenStack Keystone) with this config:
OIDCClaimPrefix "OIDC-"
OIDCResponseType "code"
OIDCScope "openid profile"
OIDCProviderMetadataURL
https://myidp.domain.country:8443/auth/realms/keystonerealm/.well-known/openid-configuration
OIDCClientID keystone
OIDCClientSecret mysecret
OIDCProviderTokenEndpointAuth client_secret_basic
OIDCCryptoPassphrase mypass
OIDCRedirectURI
http://localhost:5000/v3/auth/OS-FEDERATION/websso/oidc/redirect
OIDCOAuthVerifyJwksUri
"https://myidp.domain.country:8443/auth/realms/keystonerealm/protocol/openid-connect/certs"
If you mean client 1 (which is the one I want to limit the scope of its
actions), that's a simple webapp querying everything via REST api.
But please keep in mind that I want to protect users coming from client
1 from accessing services included in Keycloak itself (like the /account
API) and there is little I can do to protect it via the APACHE OIDC
module... and, ideally, I would like to do all this restricting inside
Keycloak, without touching every Apache (or whatever client 2) that I
have around here.
BTW, I think you are missing an URL for example [1] you wanted to show
me. Could you please re-post it?
I have the impression that I am missing something fundamental... but I
don't know what it can be.
Thanks a lot to everyone who is helping me out!
BR/Pablo
>
> Regards.
> Pedro Igor
>
> On Fri, Aug 18, 2017 at 6:00 AM, Pablo Fernandez
> <pablo.fernandez at cscs.ch <mailto:pablo.fernandez at cscs.ch>> wrote:
>
> Thanks Simon,
>
> Yes, I think we're getting closer. To avoid confusion, let me
> rename the
> originating client "A" and the resource client "B".
>
> Answer in-line:
>
>
> On 17/08/17 17:05, Simon Payne wrote:
> > Hi, i'm not sure i follow your use case then. I read your
> question to mean
> > 'how to restrict a resource server to only validating a token to
> tokens
> > requested by white listed clients.'
> It's almost right, but just inside Keycloak (so, without touching the
> client A itself or the resource server behind client B.)
>
> > audience is keycloak defaults to the client id if not
> specified. you can
> > override this to whatever you want by adding to the mappers tab.
>
> I was taking a look at the different types of Mappers for client A and
> did not find one for the audience. What kind of mapper should one use?
> Hardcoded claim? Then, the claim should be called 'aud', right?
> (I am doing everything through the web interface, btw)
>
> But then, if I do it this way, I will have to change each resource
> server, right?
>
> > re-reading your email however, it sounds like scope or roles
> might be your
> > solution. after adding the roles to either the user or service
> account
> I could add the role to the client A without using service
> accounts, right?
>
> > then you need to add the relevant authorization to each client
> in the
> > property file, mapping the resource to the role required. e.g.
> (springboot)
> >
> > keycloak.realm = master
> > keycloak.auth-server-url = xxxxx
> > keycloak.ssl-required = external
> > keycloak.resource = xxxxxx
> > keycloak.credentials.secret=xxxxxx
> > keycloak.bearer-only= true
> >
> > keycloak.security-constraints[0].authRoles[0] = user
> > keycloak.security-constraints[0].securityCollections[0].name =
> resources
> >
> keycloak.security-constraints[0].securityCollections[0].patterns[0]
> = /*
> >
> > keycloak.security-constraints[1].authRoles[0] = super_user
> > keycloak.security-constraints[1].securityCollections[0].name =
> secure resources
> >
> keycloak.security-constraints[1].securityCollections[0].patterns[0]
> = /products
>
> I understand you are refering to client B, right? Anyway, I don't find
> anywhere to change the property file from the web gui. I tried
> creating
> a new "auth-scope" in the Authorization section of client B,
> assigned it
> to the Default Resource, assigned them all to the Default
> Permission and
> all to the Default Policy (the one I defined with JS as for my first
> email: if (contextAttributes.containsValue('kc.client.id
> <http://kc.client.id>',
> 'simplewebapp')) { $evaluation.deny(); }
>
> (BTW simplewebapp is client A)
>
> No luck :( am I doing something wrong?
>
> (I did not force any role on client A, and policy is set to Enforcing)
>
> > Alternatively you can make use of the authorization services to
> achieve the
> > same thing, but must enable at the client by using
> > keycloak.policy-enforcer-config.enforcement-mode=ENFORCING I
> noticed that
> > before the auth services would work i also had to include client
> side
> > mapping of the minimum level of authorization.
> I guess here you are also speaking about client B, right?
>
> I did not understand what you mean by client side mapping of the
> minimum
> level of authorization. What client mapping? Are there levels of
> authorization?
>
> Thanks a lot for your help!
> BR/Pablo
>
>
>
> >
> >
> > Hope this helps,
> >
> > Simon.
> >
> >
> >
> >
> >
> >
> > On Thu, Aug 17, 2017 at 7:36 AM, Pablo Fernandez
> <pablo.fernandez at cscs.ch <mailto:pablo.fernandez at cscs.ch>>
> > wrote:
> >
> >> Dear Simon,
> >>
> >> Thanks for your reply.
> >>
> >> I am not quite sure your proposal would work in our case (or
> maybe I
> >> don't understand it): do you mean that the client will ask for a
> >> specific audience to be put inside the token, and that the
> other service
> >> providers would have to check that the claim is targeted
> against the
> >> right audience? That creates a big overhead if you have many
> SPs, which
> >> we do. And anyway, how can you limit a certain client to be
> issued token
> >> of a certain audience within Keycloak? And furthermore, how can
> I limit
> >> the access to the /accounts API on Keycloak for a token given
> to certain
> >> clients?
> >>
> >> It would be great to have a mechanism inside Keycloak to limit the
> >> scopes of the various clients directly, without extra work on the
> >> clients or the SPs. Am I assuming something that is wrong? What
> is the
> >> Authorization tab (and/or the Scopes one) for?
> >>
> >> Thanks a lot again,
> >> BR/Pablo
> >>
> >>
> >> On 16/08/17 15:20, Simon Payne wrote:
> >>> Pablo,
> >>>
> >>> i'm not sure whether this will be your solution directly, but
> i found out
> >>> recently that the 'aud' claim in the token is to represent the
> audience.
> >>> Now, when i used the spring-security-oauth client library i
> found that it
> >>> validated the resourceId against this aud claim.
> >>>
> >>> i thought it an unnecessary constraint at the time, but maybe
> it could be
> >>> used to restrict access by tokens, which although may have the
> correct
> >>> scope, have been issued to the incorrect or otherwise unknown
> client?
> >>>
> >>> Simon.
> >>>
> >>> On Wed, Aug 16, 2017 at 1:41 PM, Pablo Fernandez <
> >> pablo.fernandez at cscs.ch <mailto:pablo.fernandez at cscs.ch>>
> >>> wrote:
> >>>
> >>>> Dear Keycloakers,
> >>>>
> >>>> I am (almost) new to Keycloak and having trouble, and I
> thought I should
> >>>> ask you after exhausting other options, so here I am.
> >>>>
> >>>> What I would like to find is a way to confine certain web
> apps (with a
> >>>> registered client in Keycloak) from accessing any other
> client that is
> >>>> not supposed to. Specifically, I have an oidc client named
> 'keystone'
> >>>> that handles all OpenStack authentication and another oidc client
> >>>> 'simplewebapp' that is a webapp that I want to give access to
> 'keystone'
> >>>> while NOT giving access to any of the other clients (e.g.
> account,
> >>>> admin-cli, broker, etc.)
> >>>>
> >>>> Is there a way to do this?
> >>>>
> >>>> I thought about Scopes, but I see they are basically linked
> to Roles
> >>>> that I think have nothing to do with what I am doing (I
> tried, though
> >>>> creating new roles but it seems to me they don't prevent
> anything from
> >>>> happening). If I have to use Scopes, then how? Is there a
> Role that I
> >>>> can use to deny - or exclusively grant - access to another
> client? I
> >>>> also tried changing the Default Policy in 'keystone'
> Authorization tab
> >>>> to something like this (the opposite of what I wanted to do,
> to make it
> >>>> fail and see if I can use this mechanism), without success:
> >>>>
> >>>> ---
> >>>> // by default, grants any permission associated with this policy
> >>>> //$evaluation.grant();
> >>>> var context = $evaluation.getContext();
> >>>> var contextAttributes = context.getAttributes();
> >>>> if (contextAttributes.containsValue('kc.client.id
> <http://kc.client.id>', 'simplewebapp')) {
> >>>> $evaluation.deny();
> >>>> }
> >>>> $evaluation.grant();
> >>>> ---
> >>>>
> >>>> I googled and browsed and tried many different setting
> combinations
> >>>> without success, so I hope someone here could give me a hint.
> >>>>
> >>>> Thanks!
> >>>> Pablo Fernandez
> >>>>
> >>>>
> >>>>
> >>>> _______________________________________________
> >>>> keycloak-user mailing list
> >>>> keycloak-user at lists.jboss.org
> <mailto:keycloak-user at lists.jboss.org>
> >>>> https://lists.jboss.org/mailman/listinfo/keycloak-user
> <https://lists.jboss.org/mailman/listinfo/keycloak-user>
> >>>>
> >>> _______________________________________________
> >>> keycloak-user mailing list
> >>> keycloak-user at lists.jboss.org
> <mailto:keycloak-user at lists.jboss.org>
> >>> https://lists.jboss.org/mailman/listinfo/keycloak-user
> <https://lists.jboss.org/mailman/listinfo/keycloak-user>
> >>
> >>
> >> _______________________________________________
> >> keycloak-user mailing list
> >> keycloak-user at lists.jboss.org
> <mailto:keycloak-user at lists.jboss.org>
> >> https://lists.jboss.org/mailman/listinfo/keycloak-user
> <https://lists.jboss.org/mailman/listinfo/keycloak-user>
> >>
> > _______________________________________________
> > keycloak-user mailing list
> > keycloak-user at lists.jboss.org <mailto:keycloak-user at lists.jboss.org>
> > https://lists.jboss.org/mailman/listinfo/keycloak-user
> <https://lists.jboss.org/mailman/listinfo/keycloak-user>
>
>
>
> _______________________________________________
> keycloak-user mailing list
> keycloak-user at lists.jboss.org <mailto:keycloak-user at lists.jboss.org>
> https://lists.jboss.org/mailman/listinfo/keycloak-user
> <https://lists.jboss.org/mailman/listinfo/keycloak-user>
>
>
More information about the keycloak-user
mailing list