[keycloak-dev] Pluggable client authentication, Support for client authentication with signed JWT

Marek Posolda mposolda at redhat.com
Tue Aug 18 10:03:08 EDT 2015


Dne 18.8.2015 v 14:39 Bill Burke napsal(a):
> SAML client console pages have a way to import/export keys/certs.  You
> may be able to reuse/merge with that.
I already reused and merge with that whenever possible. Most of server 
logic ( ClientAttributeCertificateResource ) is reused and I also reused 
some of your angular code.

One thing, I didn't want, is storing the client private keys in keycloak 
DB, which we agreed with Stian last week (discussion with subject "Keep 
client private keys in Keycloak DB?" ).

For SAML, I think for both usecases where are keys/certs used (Signing 
SAMLRequest by client or encrypt SAML Assertion with client public key) 
is also private key not needed in Keycloak DB. Shoudn't we try to 
improve SAML as well and avoid storing private keys? IMO Client private 
keys should be exclusively owned by client and not by Keycloak server. 
If client loose the key, he can generate new keypair again.
>
> Maybe we should figure out how to merge client and user
> authenticators/flows.
yeah, I was trying to reuse whenever possible. Like 
ClientAuthenticatorFactory and AuthenticatorFactory has base superclass 
ConfigurableAuthenticatorFactory etc.


But maybe there is still space for improvement though.  Do we want to merge into one class and use generics? Like


public interface Authenticator<T> {

    void authenticate(AuthenticationContext<T> context);

}

when concrete implementation will use T as either UserModel or ClientModel ?

I was also thinking about doing abstract superclass for 
DefaultAuthenticationFlow and ClientAuthenticationFlow. But in the end, 
I added ClientAuthenticationFlow as separate class as there is lot of 
logic specific to user in DefaultAuthenticationFlow (like 
authenticator.requiresUser() etc). Another thing is that 
ClientAuthenticationFlow doesn't have access to ClientSession when 
DefaultAuthenticationFlow needs it as it maintains state between 
requests (client authentication is single request). There are few other 
similar things...

I will try to revisit and improve if possible, on the other hand having 
abstraction for everything might sometimes makes things more complex and 
harder to understand...

Marek
>
> On 8/18/2015 2:58 AM, Marek Posolda wrote:
>> I've sent PR https://github.com/keycloak/keycloak/pull/1545 for
>> #subject. Few main points:
>> - Authentication of OIDC clients is now pluggable. I've added
>> ClientAuthenticationSPI and some support classes like
>> ClientAuthenticator . There is also new flow type
>> ClientAuthenticationFlow as there are some differences between
>> authenticating clients and users (ie. for clients you don't have
>> ClientSession available etc).
>>
>> - There is new builtin flow "clients" added automatically, which can be
>> seen in "Authentication" tab in admin console . By default it has 2
>> executions:
>> -- Traditional authentication with client_id and client_secret
>> -- Authentication with signed JWT . It works in a way that client
>> generates JWT and signs it with his private key . Keycloak then verifies
>> signature with public key attached to the certificate corresponding to
>> client . Related specifications: [1] and [2] . I've implemented 6.1 and
>> 6.2 from the [1], which means that clients are able to authenticate
>> themselves for retrieve service accounts (ie. "grant_type" is
>> "client_credentials" ), but also authenticate themselves for all other
>> backchannel requests (code-to-token, refresh token etc)
>>
>> - In "Credentials" tab in admin console for Client is table with
>> available authentication mechanism. Admin needs to choose "Client Id and
>> Secret" or "Signed JWT" . For signed JWT he can either:
>> -- generate keypair + certificate and download his private key into JKS
>> or PKCS12 keystore file
>> -- upload the certificate corresponding to his existing private key .
>> In both cases is Client's private key not saved in Keycloak DB as
>> discussed in other thread last week. So just the client is exclusive
>> owner of his private key and when he loose it, he needs to generate and
>> download another one.
>>
>>
>> Possible remaining work:
>> 1) Adapters support?  I am thinking about adding simple pluggable SPI
>> for client authentication on adapter side. It will be ServiceLoader
>> based and it will choose client authentication mechanism based on the
>> credentials provided in keycloak.json in webapp. For example when there is:
>>
>> "credentials": {
>>        "secret": "password"
>> }
>>
>> it uses traditional clientId and clientSecret like now.
>>
>> When there is:
>>
>> "credentials": {
>>        "jwt": {
>>            "keystoreFile": "classpath:keystore/keystore.jks",
>>            "keystoreType": "JKS",
>>            "storePassword": "secret",
>>            "keyPassword": "secret",
>>            "tokenExpiration": 10
>>        }
>> }
>>
>> it will authenticate client with signed JWT . WDYT?
>>
>>
>> 2) Example, docs, polishing, maybe adapter tests . But most of automated
>> testing is done already. I've added ClientAuthSignedJWTTest for testing
>> signed JWT and CustomFlowTest for testing custom client authentication flow.
>>
>>
>> ETA for 1 and 2 are maybe 2-3 days of work. I will show more on the call
>> on Thursday. WDYT?
>>
>> Marek
>>
>>
>> [1] https://tools.ietf.org/html/draft-ietf-oauth-assertions-01
>> [2] https://tools.ietf.org/html/draft-jones-oauth-jwt-bearer-03
>> _______________________________________________
>> keycloak-dev mailing list
>> keycloak-dev at lists.jboss.org
>> https://lists.jboss.org/mailman/listinfo/keycloak-dev
>>

-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.jboss.org/pipermail/keycloak-dev/attachments/20150818/551c0c26/attachment.html 


More information about the keycloak-dev mailing list