Add SAML Extensions (and AuthContext) as another client note to the AuthenticationSessionModel in SamlService
by Roland
Hello,
when a SAML Request is received in Keycloak, the method loginRequest in
abstract class BindingProtocol in class
org.keycloak.protocol.samlSamlService puts the information from the request
into the AuthenticationSessionModel in this section of code:
authSession.setProtocol(SamlProtocol.LOGIN_PROTOCOL);
authSession.setRedirectUri(redirect);
authSession.setAction(
AuthenticationSessionModel.Action.AUTHENTICATE.name());
authSession.setClientNote(SamlProtocol.SAML_BINDING,
bindingType);
authSession.setClientNote(GeneralConstants.RELAY_STATE,
relayState);
authSession.setClientNote(SamlProtocol.SAML_REQUEST_ID,
requestAbstractType.getID());
What we are missing here is the SAML Extensions, which happen to be in the
SAML Request which we receive, and which we want to pass on to a brokered
external Identity Provider.
For example something like this:
ExtensionsType et = requestAbstractType.getExtensions();
List<Object> list = et.getAny();
<create some kind of String representation>
authSession.setAuthNote("SAML_EXTENSION", <the String
representation>);
In the same way we would also like access to the AuthContext through the
authSession.
I would offer to contribute this if the community approves the idea.
Thanks and Regards,
Roland
5 years, 5 months
Putting a value into a custom Protocol mapper
by Chris Smith
I'm trying to have a custom protocol mapper provide a serialized Kerberos ticket as a claim
I have updated the KerberosUsernamePasswordAuthenticator so that it gets the ticket
public Subject authenticateSubject(String username, String password) throws LoginException {
String principal = getKerberosPrincipal(username);
logger.debug("Validating password of principal: " + principal);
loginContext = new LoginContext("does-not-matter", null,
createJaasCallbackHandler(principal, password),
createJaasConfiguration());
loginContext.login();
serializedKerberosTicket = serializeTicket();
logger.debug("Principal " + principal + " authenticated succesfully");
return loginContext.getSubject();
}
private String serializeTicket() {
KerberosTicket kerberosTicket = loginContext.getSubject()
.getPrivateCredentials(KerberosTicket.class)
.stream().findFirst().get();
try (ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(bos)){
oos.writeObject(kerberosTicket);
return Base64.getEncoder().encodeToString(bos.toByteArray());
} catch (IOException e) {
logger.error("Kerberos ticket serialization failed", e);
return null;
}
}
I reviewed the SPNEGOAuthenticator and traced it's execution to see how it adds the Kerberos ticket and I do not see that as a workable approach as it is so different from the Kerberos User/Password authenticator.
Where can my custom KerberosUsernamePasswordAuthenticator put the serialized ticket so that my custom protocol mapper will get it and add it as a claim on my Access token?
I have looked and googled with no luck.
5 years, 5 months
Re: [keycloak-dev] passing SAML extensions and context to custom authenticators
by Caranzo Gideon
Hi Hynek,
Thank you for your response. Yes, I agree with you. It would be good to have this mechanism in those areas as well.
I already have a PR ready for just the SAML login portion. Is it fine with you if I submit this first so that we can use it as early as possible? We can create a separate ticket to implement similar mechanism for other SAML messages and broker endpoint which can be done in near future.
Thanks,
Gideon
-----Original Message-----
From: keycloak-dev-bounces(a)lists.jboss.org [mailto:keycloak-dev-bounces@lists.jboss.org] On Behalf Of Hynek Mlnarik
Sent: Thursday, January 24, 2019 1:58 AM
To: Gideon Caranzo <gideonray(a)gmail.com>
Cc: keycloak-dev <keycloak-dev(a)lists.jboss.org>
Subject: Re: [keycloak-dev] passing SAML extensions and context to custom authenticators
Hi Gideon,
thanks for the idea. Something like that would be a useful enhancement. The implementation would need to cover also the broker endpoint, other SAML message types (extensions are part of message types other than AuthnRequest as well), and count on several implementations of the hypothetical SamlAuthenticationPreprocessor. Could you please file an "Enhancement" JIRA?
--Hynek
On Wed, Jan 16, 2019 at 5:49 PM Gideon Caranzo <gideonray(a)gmail.com> wrote:
> Hi All,
>
> I'd like to propose a feature that allows custom authenticators to
> handle SAML extensions, authentication context and other request attributes.
>
> Right now in OIDC, all request claims are passed to custom
> authenticators which allows for customized behavior depending on the claims.
> However, this is not the case for SAML. Only attributes that are
> explicitly set (e.g. NameID) in the auth session are passed to custom authenticators.
>
> Information like SAML extension and authentication context are not
> available which limits the ability to define custom behaviors. In the
> past, we ran into similar limitation and we had to update keycloak
> core to add support for NameID attribute.
>
> To solve this, we can have an optional hook that pre-process SAML
> login request right before authentication. The hook can then extract
> the needed attributes and set it accordingly for custom authenticators to process.
>
> The pre-processing will be done in
> *SamlService.BindingProtocol.loginRequest()*:
>
> *public* *class* SamlService *extends* AuthorizationEndpointBase {
>
> *. . .*
>
> *public* *abstract* *class* BindingProtocol {
>
> . . .
>
> *protected* Response loginRequest(String relayState,
> AuthnRequestType requestAbstractType, ClientModel client) {
>
> . . .
>
> SamlAuthenticationPreprocessor preProcessor = session
> .getProvider(SamlAuthenticationPreprocessor.*class*);
>
> *if* (preProcessor != *null*) {
>
> preProcessor.process(requestAbstractType, authSession);
>
> }
>
>
>
> *return* newBrowserAuthentication(authSession,
> requestAbstractType.isIsPassive(), redirectToAuthentication);
>
> }
>
>
> Let me know what you think. Thanks.
>
> Best regards,
> Gideon
> _______________________________________________
> keycloak-dev mailing list
> keycloak-dev(a)lists.jboss.org
> https://emea01.safelinks.protection.outlook.com/?url=https%3A%2F%2Flis
> ts.jboss.org%2Fmailman%2Flistinfo%2Fkeycloak-dev&data=02%7C01%7Cgi
> deon.caranzo%40gemalto.com%7C6f947d88676b4f788b2108d681d1d529%7C37d0a9
> db7c464096bfe31add5b495d6d%7C0%7C0%7C636839135555784466&sdata=Yhpx
> 28KFJWJGa1kv1ROWWqJd3nt60YvAb0YmeKUU5Mg%3D&reserved=0
>
_______________________________________________
keycloak-dev mailing list
keycloak-dev(a)lists.jboss.org
https://emea01.safelinks.protection.outlook.com/?url=https%3A%2F%2Flists....
________________________________
This message and any attachments are intended solely for the addressees and may contain confidential information. Any unauthorized use or disclosure, either whole or partial, is prohibited.
E-mails are susceptible to alteration. Our company shall not be liable for the message if altered, changed or falsified. If you are not the intended recipient of this message, please delete it and notify the sender.
Although all reasonable efforts have been made to keep this transmission free from viruses, the sender will not be liable for damages caused by a transmitted virus.
5 years, 5 months
X.509 Authenticator - New User Identity Source
by Nemanja Hiršl
Hi,
Current implementation of X.509 Authenticator uses a number of different
mappings of a certificate to user identity.
None of provided mappings can guarantee uniqueness. It is up to CA to
choose which fields to include in SubjectDN and SAN and there might be
some unique data. In these cases we can use provided mappers to identify
users. However, if there's a need to support certificates from different
CAs, with unrelated usage of SubjectDN and SAN fields those mappers are
not sufficient.
One way to uniquely identify user is to use certificate thumbprint. For
the solution I'm working on, we have implemented SHA256-Thumbprint
mapper and it is giving us expected results.
Do you think sha256 thumbprint mapper would be a useful addition to
already existing mappers?
Should I prepare appropriate PR?
The other approach might be combination of serial number and issuer.
According to RFC 5280 the issuer name and serial number identify a
unique certificate.This is something I haven't tried, but would like to
hear your opinion.
Thanks.
References:
1. There's a nice explanation on stackoveroflow of what can be used to
uniquely identify users:
https://stackoverflow.com/questions/5290571/which-parts-of-the-client-cer...
2. There's also a discussion here:
https://issues.jboss.org/browse/KEYCLOAK-9610
3. RFC 5280: https://tools.ietf.org/html/rfc5280#section-4.1.2.2
Best regards,
Nemanja
5 years, 6 months
Infinispan error during update in ha configuration
by Мартынов Илья
Hello!
I have Keycloak 4.5.0.Final deployed in standalone-ha configuration in k8s
cluster. When I try to update Keycloak to version 6.0.1, the following
happens:
1. K8s starts new pod with version 6.0.1
2. Old pod still running, it will be terminated on successfull readiness
probe of the new pod
3. New pod discovers old pod via JGroups, cache synchronization started
4. Exception in new pod:
02-07-2019;13:34:29,220 WARN [stateTransferExecutor-thread--p25-t1]
org.infinispan.statetransfer.InboundTransferTask ISPN000210: Failed to
request state of cache work from node idp-6569c544b
-hsd6g, segments {0-255}: org.infinispan.remoting.RemoteException:
ISPN000217: Received exception from idp-6569c544b-hsd6g, see cause for
remote stack trace
at org.infinispan(a)9.4.8.Final
//org.infinispan.remoting.transport.ResponseCollectors.wrapRemoteException(ResponseCollectors.java:28)
...
Caused by: java.io.IOException: Unknown type: 132
at
org.infinispan.marshall.core.GlobalMarshaller.readNonNullableObject(GlobalMarshaller.java:681)
at
org.infinispan.marshall.core.GlobalMarshaller.readNullableObject(GlobalMarshaller.java:355)
at
org.infinispan.marshall.core.BytesObjectInput.readObject(BytesObjectInput.java:40)
Looks like this exception blocks further Keycloak startup, because nothing
happens in logs afterwards. Also, my rest service deployed as JAX-RS bean
also doesn't respond, so pod is not treated as alive by Kubernetes.
Please help.
5 years, 6 months
Java Adapter Nonce Support
by D. Richter
Hi Devs,
i did a pull request https://github.com/keycloak/keycloak/pull/6154 that
was declined as it needed a bit more discussion.
A controverse point was to add a configuration with the remark to always
add the nonce to authentication requests just like here:
https://lists.jboss.org/pipermail/keycloak-dev/2018-February/010447.html
However, adding a nonce without checking it might work when the
authentication flow requires a nonce but it's useless when it is not
checked.
This is the oAuth 2.0 spec:
https://tools.ietf.org/html/rfc6819#section-4.6.2
As described the replay protection uses a nonce so requests can only be
done once. This is the reason you should never make this the default
behaviour for an adapter.
The second topic is how to do it. The oAuth 2.0 spec does not describe how
to handle the nonce on the client side. My first idea was to use the
current authentication session which has some limitations: you can only
make a valid request when your adapter holds the session and also validates
the IDP token. This all falls apart when 1) your session is timed out but
your token is still valid 2) the Token has not been requested by the same
adapter.
To remove these limitations and still ensure the prevention of replay
attacks it would be necessary for the adapter to persist the nonce and the
expiration date of the access token. When a resource request comes with a
nonce, you allow access but also store the nonce and token expiration. When
the nonce has been stored already -> access denied. A cleanup mechanism
would also be required to keep the database clean from old nonce markers
where the token is already expired.
This variant would require a persistence layer - something i have no answer
for, especially when i think of the various existing application servers
and their Keycloak adapters.
Another option might be the Cookie. As long as it's required for resource
requests and cannot be manipulated this would be a #1 choice because it
relies on code that is already there. I'm just not sure if the premises are
given (secure and non optional cookie).
Kind Regards,
Dennis Richter
5 years, 6 months
KEYCLOAK-3205 Vault in Keycloak
by Hynek Mlnarik
Vault (read-only secure credential store) is a repeatedly requested feature
for Keycloak. A document that covers the vault design proposal has been
created in [1] and is ready for review by community.
The vault proposed in that design is intentionally simple. It should cover
use cases for passwords and other credential types that are currently
stored in database in plain text. It does not and is not intended to cover
write operations into the vault - writes should be managed by the tooling
around the vault. Externalizing encryption / decryption of secrets is also
not covered by this proposal and can follow once vault would be in place.
Review comments are appreciated.
--Hynek
[1]
https://github.com/keycloak/keycloak-community/blob/master/design/secure-...
5 years, 6 months
Google ID Broken & Devs do not care
by Nick Powers
I have wasted so much time deploying Keycloak to only learn in the end that
it doesn't support Google offline access and thus cannot retrieve Google
refresh tokens. I am not alone, there are many messages in both the
Keycloak user and dev mailing lists discussing the lack of offline access
for Google IDP on Keycloak.
When this comes up in the user mailing list the messages are generally not
responded to. Which makes sense since there is not a working solution to
receive Google refresh tokens using Keycloak's Google IDP solution. It is
broken and thus the users cannot provide a solution.
When this comes up in this (the dev) mailing list, it is again ignored or
it is debated but end up with the same sentiment, that offline access /
refresh tokens from Google IDP is not a worthwhile feature. I found many
messages in the dev mailing list, spanning from 4 years ago to current
identifying this issue and yet it remains unfixed. All it would take is to
add "access_type=offline" to the Google auth URL and yet still it is
broken, they just don't care enough to do even that simple task. They
think that it is silly that anyone would need a Google refresh token.
I found the code segment that related to Google offline access in Keycloak
and there was a comment that identified an email address of the person who
wrote that section of code. It was a Red Hat email, from regular user on
this mailing list. I reached out to him and his response was that he had
no time to respond to my query and that Red Hat does not support Keycloak.
Maybe don't put your email into code you don't want to get queries on? So,
if Red Hat is not supporting their own project, in any regard, and the devs
have no intention of fixing this bug the assumption is that Google IDP will
never be fixed.
If you landed on this message, now or in the future, in hopes of finding a
solution to get Google refresh tokens from Keycloak IDP all I can do is try
to save you some time and say that Google IDP on Keycloak is currently
broken in that regards and if the past is any indication the devs have no
intention of fixing the code to allow that access.
If any devs on this list disagree with this message then please let me know
what I have missed and point me in the direction of a solution for this
issue....... I didn't think so.
:(
5 years, 6 months
how to create a cache for a new session?
by Federico Michele Facca
Hi,
I am doing experiments for the support of "permanent" tokens. (see previous
thread on the matter).
In doing so, I thought that the best solutions was to create a separate
storage cache (as for offline sessions).
Now this is configured in the code, but configuration for this new cache
storage of course can't be found (since I haven't created it :) ) so i get
this error:
10:46:16,257 ERROR XNIO-1 task-1
[org.keycloak.services.error.KeycloakErrorHandler] Uncaught server error
org.infinispan.commons.CacheConfigurationException: ISPN000436: Cache
'permanentSessions' has been requested, but no cache configuration exists
with that name and no default cache has been set for this container
I thought this guide:
https://github.com/keycloak/keycloak/blob/master/docs/updating-database-s...
to be the solution, but 1) there is no existing db. 2) from keycloak
repository root, i can't find the path: connections/jpa-liquibase/pom.xml
Thanks for any hint!
Cheers,
Federico
--
*Dr. FEDERICO MICHELE FACCA*
*CTO, Head of Martel Lab*
+41 788075838
*MARTEL INNOVATE* <https://www.martel-innovate.com/> - INNOVATION, WE MAKE
IT HAPPEN
Click *HERE* to download Martel reports and white papers!
<https://www.martel-innovate.com/premium-content/>
Follow us on *TWITTER* <https://twitter.com/Martel_Innovate>
5 years, 6 months
Re: [keycloak-dev] Scalability Problems with the admin console
by Eugen Stan
Hi Gregor,
Replied to list as well.
La 25.07.2019 19:43, Gregor Tudan a scris:
> I like the idea. If I understood you right, you‘re proposing to request a new token after selecting a realm from the list in the admin console to edit this specific realm (maybe by the scope param)?
>
> We would still need to come up with a different solution for finding out which realm the user is allowed to edit. That seems to be the main purpose of whoami right now.
>
> - Gregor
Yes, that is what I am proposing. In our application we thought about
using scopes like: `account:123` .
For the list if accounts there should be another API that will list all
of the realms the current user has access to.
I'm pretty sure the server side implementation should be simple.
So the Admin WebApp will probably need some work and be prepared like this:
- use authenticates ( in a realm or in master ?! )
- Admin WebApp calls the list-accessible-realms API
- Admin WebApp displays the list of accessible realms
- User selects an account to manage
- Admin WebApp gets a token for that realm and uses it for the calls
You could look at it as two web applications:
The realm selector and the realm manager. In this case the realm id (and
the token to access it) is internal state for the realm manager application.
Regards,
Eugen
5 years, 6 months