I don't know Stian. We are talking about authentication and that
is what
the IDToken is all about. In fact, even Google [1] has some references
about using IDTokens as a way to *authenticate* users.
Sure, but that's to authenticate to one specific application, not to
authenticate to the IdP itself. The concept of authenticating with the IdP
with a ID token is broken.
There are also specs with extensions to OAuth2 that do allow usage of
*assertions" with the token endpoint [2] [3]. For instance, SAML and JWT
assertions.
[1]
https://developers.google.com/identity/sign-in/web/backend-auth
[2]
https://www.rfc-editor.org/rfc/rfc7523.txt
[3]
https://tools.ietf.org/html/rfc7521
On Thu, Aug 17, 2017 at 2:05 AM, Stian Thorgersen <sthorger(a)redhat.com>
wrote:
> Actually, Bill has convinced me that ID token shouldn't be used for
> authentication. If anything a special token only available in direct grant
> should be used. The problem with ID token is that it's sent to the clients
> themselves which would effectively give all clients full access to a users
> account:
>
> * User logs in to app 1 through web flows
> * App 1 gets an access token with limited roles, but also an ID token
> that could be used for authentication
> * App 1 uses the ID token to "authenticate" itself as the user to App 2
> and can now obtain an access token with more privileges then it should
>
It depends on how you set your policies.
>
> So using ID token to authenticate a user is a completely broken concept.
>
> On 15 August 2017 at 19:51, Pedro Igor Silva <psilva(a)redhat.com> wrote:
>
>> We have discussed this before (I think because of Kubernetes), I don't
>> see issues about using the IDToken as a bearer for "authentication".
Of
>> course, as long as you enforce validations that check if token can be
>> trusted.
>>
>> In fact, I was about to start a discussion around IDToken and signature.
>> In UMA 2.0 you can use different claim token formats to obtain a token
>> (RPT) from the token endpoint. There is a specific grant type for that. One
>> of the main changes we had in the specs.
>>
>> A common format is "http://openid.net/specs/openi
>> d-connect-core-1_0.html#HybridIDToken", which is about using an IDToken.
>>
>> On Tue, Aug 15, 2017 at 12:32 PM, Bill Burke <bburke(a)redhat.com> wrote:
>>
>>> I would be worried about the security implications of allowing an ID
>>> token as a way to obtain access. If you have even one client in the domain
>>> that is not fully trusted then you are toast. So how is it set up to make
>>> things easy? One "master" client is defined in realm. That client
is
>>> given permission to obtain exchange for anything. That client is marked as
>>> confidential. Generic CLI tool is configured with client id and secret of
>>> "master" client.
>>> On 8/15/17 2:50 AM, Stian Thorgersen wrote:
>>>
>>> First of all I'm not arguing against token exchange service. It's a
>>> very useful thing IMO and I can see loads of use-cases for it. I'm just
>>> wondering about how usable it will be for the CLI tool and I'm worried
>>> about how complicated it would be to setup. If the ID token was signed that
>>> could serve as a the "identity cookie" for a CLI SSO session (if ID
token
>>> is not suitable we could introduce some sort of identity token that can be
>>> used by direct grant to allow SSO sessions). Using direct grant you can
>>> then easily obtain a token for a specific client by just passing a valid
>>> "identity cookie" same way as the web browser does. Is that not
simpler to
>>> setup and use?
>>>
>>> On 14 August 2017 at 15:42, Bill Burke <bburke(a)redhat.com> wrote:
>>>
>>>> CLI tool I wrote doesn't allow token exchange, yet, but you're
>>>> correct, I'm thinking of using it to perform token exchange.
>>>>
>>>> Our ID tokens are not signed right now. Also you still need client to
>>>> client exchange so that you can "downgrade" a token to talk to
an untrusted
>>>> service. I've also added new fine-grain permissions
"exchange-from" and
>>>> "exchange-to".
>>>>
>>>> For example, lets say Client A gets token and invokes on service B
>>>> which needs to invoke on untrusted service C.
>>>>
>>>> 1. Service B asks to exchange the token created for A to talk to C
>>>> 2. Token exchange endpoint looks at issuer, its A, so it sees if
>>>> service B has permission to "exchange-from" tokens created for
A
>>>> 3. Token exchange then sees if B has permission to
"exchange-to" B.
>>>>
>>>> FYI, I'm also expanding this so that you can exchange an access
token
>>>> for a social provider token. Automatic refreshes and everything if the
>>>> provider supports it. Gonna change how client initiated linking works
too
>>>> so that instead of doing the silly hash algorithm required by the call,
>>>> clients would call the exchange first, get an error response like
"not
>>>> linked" that contained a browser URL that the client can use to
create the
>>>> link.
>>>>
>>>> Also no reason I couldn't do the same for exchange an external token
>>>> to a internal one. Would work the same as our IDP, import the user,
etc.
>>>>
>>>>
>>>> On 8/14/17 7:06 AM, Stian Thorgersen wrote:
>>>>
>>>> I'm assuming the basic token exchange service comes from the way the
>>>> CLI tool works? I.e. you login to the tool then it allows exchanging the
>>>> token for a particular CLI client?
>>>>
>>>> Would it not be better to obtain an ID token and use direct grant to
>>>> obtain a token for the client using the ID token as the authentication
>>>> mechanism?
>>>>
>>>> On 1 August 2017 at 19:10, Pedro Igor Silva <psilva(a)redhat.com>
wrote:
>>>>
>>>>> On Mon, Jul 31, 2017 at 1:54 PM, Bill Burke
<bburke(a)redhat.com>
>>>>> wrote:
>>>>>
>>>>> >
>>>>> >
>>>>> > On 7/31/17 12:18 PM, Bill Burke wrote:
>>>>> >
>>>>> >
>>>>> >
>>>>> > On 7/31/17 11:35 AM, Pedro Igor Silva wrote:
>>>>> >
>>>>> > On Fri, Jul 28, 2017 at 5:24 PM, Bill Burke
<bburke(a)redhat.com>
>>>>> wrote:
>>>>> >
>>>>> >> I've implemented a simple token exchange API [1] that
allows you to
>>>>> >> exchange an access token created for one client to another
>>>>> client. The
>>>>> >> REST API follows the oauth token exchange api [2] very
loosely.
>>>>> >>
>>>>> >> subject_token: a keycloak access token
>>>>> >>
>>>>> >> audience: takes a client id
>>>>> >>
>>>>> >> It then converts the access token created for one client
and
>>>>> converts it
>>>>> >> to another. It lives under the token endpoint.
>>>>> >>
>>>>> >> The security model is as follows:
>>>>> >>
>>>>> >> * Authenticate calling client the same way as password
grant.
>>>>> >>
>>>>> >> * The calling client must have service account enabled
>>>>> >>
>>>>> >> * Service account must have a realm role
"token-exchanger" grant
>>>>> edto it
>>>>> >> or, it must have a client role "token-exchanger"
granted to it.
>>>>> This
>>>>> >> exchanger client role is a role defined by the target client
you
>>>>> are
>>>>> >> exchanging the token to.
>>>>> >>
>>>>> >>
>>>>> >> Is this a good security model? I'm thinking of not
creating these
>>>>> roles
>>>>> >> right now and to enable support for exchange would require
>>>>> defining the
>>>>> >> roles specified above.
>>>>> >>
>>>>> >
>>>>> > I think roles are too coarse-grained to represent this kind of
>>>>> policy. A
>>>>> > better option would be to explicitly define the clients that
are
>>>>> allowed to
>>>>> > exchange tokens for a particular resource server. Eg.:
>>>>> >
>>>>> > RS A allows Client B, C and D to exchange their tokens where
the
>>>>> target
>>>>> > audience is RS A (or if using "resource", a specific
resource in RS
>>>>> A).
>>>>> >
>>>>> >
>>>>> > I changed it a little. actors are:
>>>>> >
>>>>> > * Authenticated client asking for change
>>>>> > * Clients that are the audience of the token being exchanged
>>>>> > * Client you want the token to be exchanged to
>>>>> >
>>>>> > So, the authenticated client must be in the audience of the
token
>>>>> being
>>>>> > exchanged, or, have permission to exchange from that particular
>>>>> audience.
>>>>> > The authenticated client also must have permission to exchange
to
>>>>> the
>>>>> > audience it wants to exchange to.
>>>>> >
>>>>> > Good idea to change it to use the fine grain admin permissions.
>>>>> There's a
>>>>> > couple of issues/problems with doing this that I think are
easily
>>>>> done:
>>>>> >
>>>>> > * public clients can't have service accounts.
>>>>> > * Client Policy looks at kc_client_id attribute which is pulled
>>>>> from the
>>>>> > issuedFor claim in the token. This isn't correct as we
permission
>>>>> checks
>>>>> > based on the authenticated client, not the token.
>>>>> >
>>>>> > So I'll have to create a new Identity type that either wraps
the
>>>>> service
>>>>> > account or ClientModel and sets the "kc_client_id"
property.
>>>>> >
>>>>>
>>>>> Our policy evaluation engine is based on the claims within the
token.
>>>>> The
>>>>> "issueFor" is basically the "azp" claim from
OIDC. In fact, we don't
>>>>> even
>>>>> need that "kc_client_id". We could make this configurable
though, and
>>>>> let
>>>>> users decide whether they want to check the "authenticated
client" or
>>>>> "azp"
>>>>> ?
>>>>>
>>>>> Btw, I'm about to finish UMA Grant Type, one of the changes
I'm doing
>>>>> for
>>>>> UMA 2.0. My changes will conflict with yours. Are you going to merge
>>>>> your
>>>>> changes soon ?
>>>>>
>>>>> Another thing I noticed is that maybe we could have a SPI for custom
>>>>> grant
>>>>> types. What you did and what I'm doing may justify a specific SPI
for
>>>>> plugging custom grant types. Maybe too much, but maybe a nice to
have.
>>>>>
>>>>>
>>>>> >
>>>>> >
>>>>> > Bill
>>>>> >
>>>>> _______________________________________________
>>>>> keycloak-dev mailing list
>>>>> keycloak-dev(a)lists.jboss.org
>>>>>
https://lists.jboss.org/mailman/listinfo/keycloak-dev
>>>>>
>>>>
>>>>
>>>>
>>>
>>>
>>
>