[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