Giter Club home page Giter Club logo

keycloak-wsfed's Introduction

WS-Federation for Keycloak

The purpose of this module is to support the WS-FED protocol in Keycloak. Only Web (Passive) requestors are supported, as defined in section 13 of the specification. It should be noted that the optional elements of the protocol (attribute services and pseudonym services) are not currently supported. However, in its current capacity the WS-Fed protocol can be used for communication with:

  • Keycloak clients (WS Resources), with Keycloak acting as an IdP/STS.
  • Other IdPs, with Keycloak acting as an Identity Broker.

The WS-Fed protocol does not specify the format of the tokens, but this module supports SAML 2.0 and SAML 1.1 tokens for its operations.

This module is currently working on 8.0.1 (check tags for compatibility with previous Keycloak versions)

How to build

Before building this project with a basic mvn clean install, you need to first build cloudtrust-common.

git clone [email protected]:cloudtrust/cloudtrust-parent.git
cd cloudtrust-parent
mvn clean install

Then build keycloak-wsfed:

git clone [email protected]:cloudtrust/keycloak-wsfed.git
cd keycloak-wsfed
mvn clean install

If you get an error telling Could not find artifact org.keycloak.testsuite:integration-arquillian-tests:pom, you might build Keycloak with:

mvn install -Pconsole-ui-tests -DskipTests

How to install

After building it, you can automatically install this module using the following command line:

./keycloak-wsfed/install.sh {path-to-keycloak}

You can uninstall it with:

./keycloak-wsfed/install.sh {path-to-keycloak} -u

But you can choose to manually install it:

Copy files

This is an example with Keycloak available at /opt/keycloak

#Create layer in keycloak setup
install -d -v -m755 /opt/keycloak/modules/system/layers/wsfed -o keycloak -g keycloak

#Setup the module directory
install -d -v -m755 /opt/keycloak/modules/system/layers/wsfed/com/quest/keycloak-wsfed/main/ -o keycloak -g keycloak

#Install jar
install -v -m0755 -o keycloak -g keycloak -D target/keycloak-wsfed-8.0.1.jar /opt/keycloak/modules/system/layers/wsfed/com/quest/keycloak-wsfed/main/

#Install module file
install -v -m0755 -o keycloak -g keycloak -D module.xml /opt/keycloak/modules/system/layers/wsfed/com/quest/keycloak-wsfed/main/

Enable module & load theme

layers.conf

layers=keycloak,wsfed

standalone.xml

...
<web-context>auth</web-context>
<providers>
    <provider>module:com.quest.keycloak-wsfed</provider>
    ...
</providers>
...
<theme>
    <modules>
            <module>
                    com.quest.keycloak-wsfed
            </module>
    </modules>
    ...
</theme>
...

After that you need to set the Admin Console theme to wsfed in the master realm and in the realm with the WS-FED clients, then restart Keycloak.

How to use

How to setup a Keycloak client

In this section we will explain how to setup a Keycloak client. We will use two types of servers to act as WS-Fed Resources (Service Providers) for our example: The first is an IdP test client, while the second is Sharepoint 2013.

Creating a client

A WS-Fed client is added as any other: go to the Clients menu item and create a new client, making sure that in the "Add Client" screen, the client protocol, is wsfed. Normally, any value can be used for the Client ID, as long as it is shared with the WS-Fed resource.

A small side note: in WS-Fed parlance, the actual term for Client ID is Realm, and is the value shared in the wtrealm URI query. This can obviously lead to confusion when working with Keycloak.

Settings tab

The values Name, Description, Enabled, Consent required and Client template are the same general parameters for clients as described in the Keycloak documentation for SAML clients.

The following set of options are protocol specific: the SAML Assertion Token Format option allows the use of SAML 1.1 or SAML 2.0 tokens. The Front Channel Logout option determines if the logout requires a browser redirect to the client (for true) or if the server performs a background invocation (forfalse). The Encrypt Assertions option allows the SAML Assertion to be encrypted with the client's public key.

The last set of options concern the URIs of the client. The values Root URL, Valid Redirect URIs and Base URL are the same as those described in the Keycloak documentation for SAML clients.

SAML Keys tab

This tab is only available if the Encrypt Assertions setting was enabled in the Settings tab. As with the SAML client, it is possible to generate and export a key pair, or to import a certificate from a JKS file, PKSC12 file or a PEM certificate file. However, the imported certificate MUST be RSA, or there will be an error during runtime.

Mappers tab

Mappers are generally handled in the same way as described as described in the Keycloak documentation on mappers.

Mappers are equivalent to those from the SAML client, however, there is an extra mapper present in the WS-Fed SAML mappers: a SAML javascript mapper. Its use is almost analog to the OIDC script mapper: the nashorn javascript engine is used to evaluate the input script, and the last statement is the value that will be returned in the SAML attribute. The sole difference to the OIDC variant is that the SAML javascript mapper can handle Iterables or arrays as a return value: the result will either be multiple attributes, or a single attribute with a grouped value, depending on the value of the Single Group Attribute option.

Installation tab

The installation tab gives access to the WS-Fed metadata, which can be used to configure the WS-Fed resource. This information can also be accessed at http[s]://<hostname>:<port>/auth/realms/<realm>/protocol/wsfed/descriptor.

Example: configuration with the IdP test client

For this example we will be running Keycloak with the WS-Fed module installed on localhost:8080 and the IdPTestClient on localhost:7000.

Realm setup

Create a realm TestRealm, with the roles user, testUser and groupUser in addition to Keycloak's default roles. In this realm, create a user with the following characteristics:

  • Username: test.testuser
  • Email: [email protected]
  • Firstname: test
  • Lastname: testuser
  • User Enabled: on
  • Email Verified: off

In credentials, set the password to password (with Temporary set to off). In Role Mappings, and the roles user and testUser.

Client setup

Go to the Clients menu, and create a new client. In the "Add Client" page screen choose wsfed for the client protocol, WSFedTestClient for the Client ID and save.

In the Settings tab, set the Valid Redirect URIs to http://localhost:7000/*, leave the rest of the values unchanged and save.

In the Mappers tab, create a new mapper. For Mapper Type select SAML Role list, and then set the Name to SAML Role mapper and the SAML Attribute Nameformat to Basic before saving.

Go to the Installation tab, and select WSFed Metadata IDP Descriptor, the values will be useful for the next step.

IdPTestClient setup

Clone the idp-test-client repository, and follow the instructions to build the jar.

Create a new certif.cer file. The format of the file should be the following:

-----BEGIN CERTIFICATE-----
CERTIFICATE_VALUE
-----END CERTIFICATE-----

With CERTIFICATE_VALUE being the value from the "X509Certificate" field from the WSFed Metadata IDP Descriptor.

Create a keystore with the command:

keytool -importcert -file certif.cer -keystore localstore.jks -alias "TestRealm"

And choose localpass as the password (make sure that the java keytool is on the PATH).

Create the following fediz-config.xml file for the ws-fed configuration of the IdPTestClient:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<FedizConfig>
    <contextConfig name="/">
        <audienceUris>
            <audienceItem>http://localhost:7000/</audienceItem>
        </audienceUris>
        <certificateStores>
            <trustManager>
                <keyStore file="file:///absolute/path/to/localstore.jks" password="localpass" type="JKS" />
            </trustManager>
        </certificateStores>
        <trustedIssuers>
            <issuer certificateValidation="PeerTrust" />
        </trustedIssuers>
        <protocol xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="federationProtocolType" version="1.2">
            <issuer>http://localhost:8080/auth/realms/TestRealm/protocol/wsfed</issuer>
            <realm>WSFedTestClient</realm>
            <reply>/j_spring_fediz_security_check</reply>
        </protocol>
        <logoutURL>/wsfedLogout</logoutURL>
        <logoutRedirectTo>/performLogout</logoutRedirectTo>
    </contextConfig>
</FedizConfig>

Note that the "issuer" is the value in "EndpointReference" from the WSFed Metadata IDP Descriptor.

Then, making sure that the jar and the fediz-config.xml are in a same directory, run:

java -jar IdPTestClient.jar --fediz.configFilePath=fediz-config.xml --connection.protocol=WSFED

The website at localhost:7000 will have the option to login with WS-Fed.

Example: configuration in Sharepoint 2013

The realm setup for this example is the same as the one for the IdPTestClient setup.

Go to the Clients menu, and create a new client. In the "Add Client" page screen choose wsfed for the client protocol. For Sharepoint, the Client ID must be in the urn format, so we will have urn:testsharepoint:wsfed (with an incorrect format, Sharepoint will throw an Unknown SPRequest error). Save the values.

Sharepoint will only accept HTTPS connections (this is also true for the Keycloak endpoint), and SAML 1.1 tokens. Imagining that Sharepoint is also on the localhost, we have the following values in the Settings tab:

  • SAML Assertion Token Format: SAML1.1
  • Valid Redirect URIs: https://localhost/*

In the Mappers tab create the following mappers:

  1. Name: SAML role list, Mapper Type: SAML Role List, Role attribute name: Role, SAML Attribute NameFormat: Basic
  2. Name: SAML upn, Mapper Type: SAML User Property, Property: username, SAML Attribute Name: upn, SAML Attribute NameFormat: Basic
  3. Name: SAML email, Mapper Type: SAML User Property, Property: email, SAML Attribute Name: emailaddress, SAML Attribute NameFormat: Basic

In the Installation tab, copy the content of the "X509Certificate" field from the WSFed Metadata IDP Descriptor to a new certif.cer file.

Next is setting up Sharepoint to use the Keycloak server. The following guide to configure ADFS with Sharepoint describes the steps from the Configure SharePoint Web Application section with pictures. The basic steps are the following:

Step 1: Run the following powershell script as administrator from the SharePoint 2013 Management Shell:

$cert = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2("Path\To\certif.cer")

### This section should only be necessary for self-signed certificates ###
 $tokenSigningCertificateName = "Keycloak Cloudtrust TestRealm"
 if (Get-SPTrustedRootAuthority -Identity $tokenSigningCertificateName -ea "silentlycontinue") {
     Write-Host "Signing certificate already trusted."
   }
   else {
     Write-Host "Adding signing certificate to SharePoint trusts."
     New-SPTrustedRootAuthority -Name $tokenSigningCertificateName -Certificate $cert
   }
### end section ###

 $idClaim = New-SPClaimTypeMapping -IncomingClaimType "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress" -IncomingClaimTypeDisplayName "Email address" -SameAsIncoming
 $map1 = New-SPClaimTypeMapping -IncomingClaimType "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/upn" -IncomingClaimTypeDisplayName "UPN" -SameAsIncoming
 $map2 = New-SPClaimTypeMapping -IncomingClaimType "http://schemas.microsoft.com/ws/2008/06/identity/claims/role" -IncomingClaimTypeDisplayName "Role" -SameAsIncoming

 $realm = "urn:testsharepoint:wsfed"
 $signinurl = "https://localhost:8443/auth/realms/TestRealm/protocol/wsfed"
 $ap = New-SPTrustedIdentityTokenIssuer -Name "KeycloakTestRealm" -Description "Trust to Keycloak" -Realm $realm -ImportTrustCertificate $cert -ClaimsMappings $map1, $map2, $idClaim  -SignInUrl $signinurl -IdentifierClaim $idClaim.InputClaimType
 $ap.UseWReplyParameter = $true
 $ap.Update()

Note that the $signinurl is the value in "EndpointReference" from the WSFed Metadata IDP Descriptor.

Step 2: With Sharepoint 2013 Central Administration, go to Manage Web Applications > Sharepoint - localhost:443 > Authentication Providers > default, and under "Trusted Identity provider" select KeycloakTestRealm.

When going to your Sharepoint at https://localhost, you will now have the option to log in with KeycloakTestRealm

How to setup a Keycloak identity broker

We will explain here how to setup identity brokering using two instances of Keycloak: one as identity broker, and the second as external IdP. Naturally, for this to work, the WS-Fed module must be installed on both instances of Keycloak.

Setting up the identity broker

Go to the Identity Providers menu item and create a new identity provider selecting WS-Fed from the list.

The first part of the settings are the general IdP settings, described in the Keycloak documentation. The only things of note are that:

  • The alias can be set to any value, it serves as the identifier of the identity broker - external IdP link.
  • The First Login Flow should be set to first broker login in most cases. This means that Keycloak will create a local registration of any external users at first login, create a link between the local and external user for subsequent logins.

The endpoint information from the external IdP must be setup in the WS-Fed configuration section. For a Keycloak external IdP, this can be obtained at the address:

http[s]://{host:port}/auth/realms/{realm-name}/protocol/wsfed/descriptor

This will give the following information:

  • Single Sign-On Service URL (in the PassiveRequestorEndpoint section)
  • Single Logout Service URL (in the PassiveRequestorEndpoint section, the same as the Single Sign-On Service URL)
  • Validating X509 Certificates (in the X509Certificate tags). This is only used if the Validate Signature option is set to on (which is recommended).

The remaining options are:

  • WS-Fed Realm: This is the name of the client in the Keycloak external IdP. The value is unimportant as long as it is the same in both the configuration of the identity broker and the external IdP.
  • Backchannel Logout: set to "on" if the external IdP supports the Backchannel logout
  • Handle Empty Action as wsignoutcleanup1.0: normally for the clean-up phase of a sign-out, the wa action must be set to wsignoutcleanup1.0, but with this option activated, an empty wa will be considered as a cleanup.

Setting up the client (WS Resource)

On the external IdP Keycloak, go to the Clients menu item and create a new client, selecting wsfed for the Client Protocol. The Client ID value must be set to the same value as in the WS-Fed Realm value on the Keycloak identity broker.

In the Settings tab, the only important elements to set are:

  • the SAML Assertion Token Format, which specifies the type of token to use. Currently only SAML 1.1 and 2.0 tokens are supported.
  • the Valid Redirect URIs parameter. For a Keycloak identity broker, this value MUST be set to the value of the Redirect URI in the settings tab.
Using mappers to automatically get first broker login information

If no mappers are setup, upon the first login using Keycloak as an identity broker, and after authentication with the external IdP is successful, Keycloak will display a form to get the missing information. The information required will be: username, email, first name and last name. The username will always be set, as Keycloak requires this information and will use the subject information if necessary, but it is possible to modify it.

However, it is also possible to set this information by passing the information as attributes in the SAML assertion. If all information is provided, Keycloak will skip the form, and directly create the user. Currently however, this only works with SAML 1.1 assertions.

To get the information, the following mappers must be created in the client:

  • A mapper for the username: Should be of type SAML User Property. The property should be set to username. The SAML Attribute Name MUST be set to name.
  • A mapper for the email: Should be of type SAML User Property. The property should be set to email. The SAML Attribute Name MUST be set to emailaddress.
  • A mapper for the first name: Should be of type SAML User Property. The property should be set to firstName. The SAML Attribute Name MUST be set to givenname.
  • A mapper for the last name: Should be of type SAML User Property. The property should be set to lastName. The SAML Attribute Name MUST be set to surname.

keycloak-wsfed's People

Contributors

alistairdoswald avatar braoru avatar brat000012001 avatar dseuru avatar fperot74 avatar sebzal avatar vanrar68 avatar vloup avatar yelhouti avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

keycloak-wsfed's Issues

Create a SAML javascript mapper

The idea is to create a generic mapper capable of creating attributes from a javascript description. These mappers could then be used to create values from any value present in the context. Such a mapper may even be able to call an external API to get such information.

The idea is the following: create a mapper similar to the org.keycloak.protocol.saml.mappers.UserAttributeStatementMapper (or corresponding com.quest.keycloak.protocol.wsfed.mappers.SAMLUserAttributeStatementMapper), however in the transformAttribute evaluate a javascript code to obtain the attribute rather then obtaining it from a user's attributes.

Such a use of javascript in keycloak is already done, for example, for the Authorization module, with the javascript-based policy.

build jar - deps?

how i can build jar?

git clone [email protected]:cloudtrust/keycloak-wsfed.git
cd keycloak-wsfed
mvn clean install
[INFO] Scanning for projects...
Downloading from central: https://repo.maven.apache.org/maven2/io/cloudtrust/kc-cloudtrust-module/8.0.1/kc-cloudtrust-module-8.0.1.pom
[ERROR] [ERROR] Some problems were encountered while processing the POMs:
[FATAL] Non-resolvable parent POM for io.cloudtrust:keycloak-wsfed-parent:8.0.1: Could not find artifact io.cloudtrust:kc-cloudtrust-module:pom:8.0.1 in central (https://repo.maven.apache.org/maven2) and 'parent.relativePath' points at wrong local POM @ line 6, column 13
 @
[ERROR] The build could not read 1 project -> [Help 1]
[ERROR]
[ERROR]   The project io.cloudtrust:keycloak-wsfed-parent:8.0.1 (/private/tmp/keycloak-wsfed/pom.xml) has 1 error
[ERROR]     Non-resolvable parent POM for io.cloudtrust:keycloak-wsfed-parent:8.0.1: Could not find artifact io.cloudtrust:kc-cloudtrust-module:pom:8.0.1 in central (https://repo.maven.apache.org/maven2) and 'parent.relativePath' points at wrong local POM @ line 6, column 13 -> [Help 2]
[ERROR]
[ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch.
[ERROR] Re-run Maven using the -X switch to enable full debug logging.
[ERROR]
[ERROR] For more information about the errors and possible solutions, please read the following articles:
[ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/ProjectBuildingException
[ERROR] [Help 2] http://cwiki.apache.org/confluence/display/MAVEN/UnresolvableModelException
git clone [email protected]:cloudtrust/cloudtrust-parent.git
cd cloudtrust-parent
mvn clean install
Cloning into 'cloudtrust-parent'...
remote: Enumerating objects: 12, done.
remote: Counting objects: 100% (12/12), done.
remote: Compressing objects: 100% (11/11), done.
remote: Total 187 (delta 2), reused 7 (delta 1), pack-reused 175
Receiving objects: 100% (187/187), 52.50 KiB | 590.00 KiB/s, done.
Resolving deltas: 100% (46/46), done.
[INFO] Scanning for projects...
Downloading from central: https://repo.maven.apache.org/maven2/org/keycloak/keycloak-parent/8.0.1/keycloak-parent-8.0.1.pom
Downloaded from central: https://repo.maven.apache.org/maven2/org/keycloak/keycloak-parent/8.0.1/keycloak-parent-8.0.1.pom (75 kB at 85 kB/s)
Downloading from central: https://repo.maven.apache.org/maven2/org/keycloak/testsuite/integration-arquillian-tests/8.0.1/integration-arquillian-tests-8.0.1.pom
[ERROR] [ERROR] Some problems were encountered while processing the POMs:
[FATAL] Non-resolvable parent POM for io.cloudtrust:kc-cloudtrust-testsuite:8.0.1: Could not find artifact org.keycloak.testsuite:integration-arquillian-tests:pom:8.0.1 in central (https://repo.maven.apache.org/maven2) and 'parent.relativePath' points at no local POM @ line 5, column 13
 @
[ERROR] The build could not read 1 project -> [Help 1]
[ERROR]
[ERROR]   The project io.cloudtrust:kc-cloudtrust-testsuite:8.0.1 (/private/tmp/cloudtrust-parent/kc-cloudtrust-testsuite/pom.xml) has 1 error
[ERROR]     Non-resolvable parent POM for io.cloudtrust:kc-cloudtrust-testsuite:8.0.1: Could not find artifact org.keycloak.testsuite:integration-arquillian-tests:pom:8.0.1 in central (https://repo.maven.apache.org/maven2) and 'parent.relativePath' points at no local POM @ line 5, column 13 -> [Help 2]
[ERROR]
[ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch.
[ERROR] Re-run Maven using the -X switch to enable full debug logging.
[ERROR]
[ERROR] For more information about the errors and possible solutions, please read the following articles:
[ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/ProjectBuildingException
[ERROR] [Help 2] http://cwiki.apache.org/confluence/display/MAVEN/UnresolvableModelException

Test the WS-Fed module with other clients

Currently, the WS-Fed module has only been tested with sharepoint 2013. It should also be tested at least with sharepoint 2016 and Microsoft's on premise CRM.

The results must be documented and in case of problems, new issues created.

Frontchannel logout problem

The way Keycloak is chaining the WSFED logout requests when a user is connected to multiple WSFED clients can lead to the user not being disconnected from some of these clients.

Imagine the following scenario:

  • a user is connected to 3 WSFED clients
  • the user clicks on the logout link in Client1
  • Client1 sends wa=signout1.0&wreply=LandingPage to Keycloak
  • Keycloak sends (via browser redirect) wa=signoutcleanup1.0&wreply=keycloakurl to Client2
  • Client 2 redirects the browser to Keycloak
  • Keycloak sends (via browser redirect) wa=signoutcleanup1.0&wreply=keycloakurl to Client3
  • Client 3 redirects the browser to Keycloak
  • Keycloak redirects the browser to Client1 landing page

This is how things are supposed to work in a frontchannel logout scenario (exactly like for SAML but without the token)
The problem is that a few well known WSFED clients (namely Microsoft Sharepoint and Exchange OWA) won't make use of the wreply parameter when receiving a wa=signoutcleanup1.0 request. Keycloak will never get a chance to trigger a logout request directed at Client2 and Client3.
In the above scenario this means that after clicking the "logout" link in Client1, the user will still have a valid session in Client2 and Client3 and even worse, will have no clue about it.

A solution would be the following scenario:

  • a user is connected to 3 WSFED clients
  • the user clicks on the logout link in Client1
  • Client1 sends wa=signout1.0&wreply=LandingPage to Keycloak
  • Keycloak sends a response containing an iFrame pointing to Client2.logoutURL and an autoload form pointing to himself
  • Keycloak sends a response containing an iFrame pointing to Client3.logoutURL and an autoload form pointing to himself
  • Keycloak redirects the browser to Client1 landing page

This way the logout requests initiated by Keycloak are independent of the client behaviour.
Ideally, upon receiving a wa=signout1.0 request Keycloak could send a single response containing multiple iFrames pointing to the connected clients logout URLs in order to trigger all logouts in the same request (just like ADFS does) but that would require changes at Keycloak level.

I've implemented and tested this successfully with Sharepoint. I can submit a PR with both the current behavior and the iFrame logout as an alternative. Let me know

Define and implement functional tests

Currently the authorization module is only tested through unit tests. However, we must define functional tests that guarantee that the functional requirements have been met.

These test must first be written down for human execution, then automated.

Add encryption for SAML2.0 tokens

Currently, the WS-Fed module does not support the encryption of SAML 2.0 tokens, even though this is supported for SAML clients. We should add this functionality for WS-Fed clients as well.

Migrate to Keycloak 8.0.1

Keycloak release version 8.0.1 has been released a few days ago. To keep the release schedule of keycloak-wsfed not too far behind the keycloak releases, it would be a good idea to migrate the module to KC 8.0.1. See #40

Add documentation on how to use the keycloak WS-Fed module

Currently, there is no documentation on how to setup a WS-Fed client or WS-Fed identity broker from within the GUI.

We must create this documentation, explaining the different fields and options. An example of setup with a sharepoint server should also be described.

WS-fed 404 login timeout error on Exchange2016 OWA

Currently, the WS-Fed module has only been tested with SharePoint 2013. It should also be tested at least with exchange 2016-OWA.

I tried to do it for myself, but encountered 440 "Login Timeout" :

Can I get some help? Thanks so much!

login_hint issue

Hi,

We would like to raise a question about the support for passing a login_hint to Keycloak via the keycloak wsfed implementation.

Let me discuss our setup and what we are trying to achieve.
We have an on premise Microsoft Active Directory Federation Services (ADFS). Some of our identities are stored in Azure B2C. Unfortunately there is no possibility to link ADFS directly with Azure B2C, therefore we have put Keycloak in between. We are aware that Microsoft is working on federating ADFS directly with Azure B2C, but it's still in private preview.

ADFS -> keycloak: keycloak is identity provider for ADFS, ADFS is defined as client on keycloak.
keycloak -> Azure B2C: Azure B2C is identity provider for keycloak.

We have customized the home realm detection on ADFS in order to dispatch the user to the correct identity provider, based upon their username. (e.g. internal employees to our Active Directory, other users to Azure B2C, ...)
In this case we are experiencing an issue impacting the end user experience, because we are unable to pass the username (via login_hint) from the ADFS home realm detection to Azure B2C login page. This causes end users to require entering their username twice. Once on the ADFS signin page (home real detection), and a 2nd time on the Azure B2C login page on which they land after being redirected from the ADFS HRD.

In a previous version of our setup Keycloak was federated with ADFS via SAML-P, but we got indications from Microsoft that it was not possible to pass a login_hint via SAML-P. Via wsfed it's possible to pass the login_hint from ADFS over WS federation.
In recent versions of keycloak it's also possible to pass the login_hint to the identity provider (Azure B2C) defined in Keycloak.

Unfortunately it seems that the login_hint is passed to keycloak but, is not processed. The login_hint is lost at the first wsfed request on keycloak.

Any advise on this topic?

  • Request on ADFS containing login_hint
    image

  • 1st request on keycloak containing login_hint... but in subsequent requests the login_hint is lost
    image

support for ws-trust

i don't believe this extension supports WS-Trust as well, does it?
I am seriously planning to use this extension for what it provides, Any idea what would be the effort to implement it in this extension itself?

Define and implement security tests for WS-FED based on the protocol

The WS-Fed module is currently functional, but no tests exist to ensure that the code is secure. The Section 16 of the Ws-Fed protocol describes the security considerations for the protocol.

The keycloak-wsfed code must be reviewed to ensure that those security concerns are met. In addition, other security concerns are raised throughout the document. These must also be considered and verified against the existing code.

All security considerations should also, if applicable, be formulated in forms of tests that can be unit or functionally tested.

Add per-client signing key for WS-Fed clients

Currently, the WS-Fed module uses the realm key for Signing SAML tokens. However, in a paper that presents a proof for WS-Fed being secure, one of the requirements is that the key used to sign WS-Fed messages is not used to sign messages from other protocols. To follow this recommendation, we should add an option to use a key specifically used by the client.

When the option is activated, it should generate a private-public key pair for the client (as in the SAML client), but keep the private key inaccessible (as for the realm key). It should have the option to regenerate a new private-public key pair, and to import a private-public key pair. Deactivating the option must not erase the key, just revert to using the realm key.

Migrate to Keycloak 11.x+

Sorry, we don't have a CI which publishes our components to a public repository. We only >have them in a private one.
Note that we are planning to migrate to Keycloak 10.x soon (and the 11.x when it will be >available)

Originally posted by @fperot74 in #43 (comment)

What is the status of this migration, any planned release date?

Single logout issue

Hi!

When a WSFed client sends a signout request to keycloak and the user is connected to multiple WSFed clients, keycloak will send a backchannel logout request to all other connected clients. After reading the code, the URL used to perform the backchannel logout is the first URL found in the "Valid Redirect URIs" setting of the client. This is a bad idea because the order of the values in the "Valid Redirect URIs" list cannot be chosen/forced.

Is it possible to store the backchannel logout URL in a dedicated field or use an existing field like "Admin URL" ?
If not possible it should at least be mentioned in the "Valid Redirect URIs" tooltip that the first value of the list will also be used for backchannel logout purpose

Thanks
Regards

--
Joaquim

Can add an samlple for Exchange2013-OWA login ?

Currently, the WS-Fed module has only been tested with sharepoint 2013. It should also be tested at least with exchange 2013-OWA .

I tried to do it for myself , but encountered 440 "Login Timeout" :

ModuleName
ADFSFederationAuthModule
Notification
AUTHENTICATE_REQUEST
HttpStatus
440
HttpReason
Login Timeout
HttpSubStatus
0
ErrorCode
The operation completed successfully.
(0x0)
ConfigExceptionInfo

Can I get some help ? Thanks so much !

Should the module issue a warning or an error if the WS-Ressource isn't secured (over https)

A 2005 study formally proves that WS-Fed is secure under certain conditions. One of the important conditions of that proof relies on the fact that the communication between the user and the WS Ressource is done over a secure channel. Currently, this can certainly be done, but should we ensure this by making the use of non-secure channels impossible (error message and refusal to save), or at least warn the user that without the secure channel the IDP and client are vulnerable?

How to customize the client settings page

Hi,
I have been finally able to work on integrating WS-Fed/SAML 1.1 related changes from my repo. One change I've been struggling to bring over are changes to the partials\client-detail.html and js\clients.js. I've made changes to these files to customize the appearance of the client settings page to expose WS-Fed related controls to the user, but the changes are not getting loaded. Before stepping through the code to figure out what the problem is, I figure I'd ask, perhaps someone had run into the same problem before.
Thanks!

Client installation page is broken

Moving to the Client>Installation page for a WS-Fed Client will result in a clearly broken page with the template exposed instead of having a normal page from which the installation details may be obtained.

A workaround is available, as the necessary information can be obtain with the https://<address:port>/auth/realms/<Realm name>/protocol/<protocol type>/descriptor URL.

This should however be corrected so that the information can be obtained as for clients of the other protocols.

how to import x509 to keycloak

Hi Guys,

I set up my keycloak with wsfed and it seems to be working.
Although every time I restart keycloak and re-import the realm I will end-up with a different x509 cert for my wsfed clients.

Is there any way to import the x509 certificate for wsfed with the realm import? I realized it is not client specific as every client will have the same x509 certification in the installation tab.

Thanks

Increase in-code documentation

The in-code documentation is currently lacking. All classes should have a javadoc explaining what the class does, and what the method does. As keycloak code isn't well commented (to say the least), this module's javadoc should go a bit further than necessary to also somewhat explain the underlying keycloak classes being used.

Define and implement security tests for WS-FED based on known exploits

The WS-Fed module is currently functional, but no tests exist to ensure that the code is secure. There have been known exploits against the WS-Fed protocol for which the implementation was incorrect.

A set of tests should be written and then translated into automatic tests (unit, functional), to be run against the keycloak-wsfed implementation.

Review use of themes

Currently modifications to the GUI uses the keycloak theme method. However, this might be unnecessary, by directly overwriting the keycloak theme, which could lead to a simpler deployment. This should be looked into and, might be a target for migration to keycloak 4, as the use of themes changes.

Use Arquillian instead of mocks

Currently the WS-Fed code is tested with Mockito for all data that would be coming from keycloak or the database. However, in the Keycloak project they use Arquillian to test their protocol functionalities. In order to bring our testing procedures closer to theirs, we should also use Arquillian.

The current tests should thus be replaced with tests showing the same functionalities, but using a "real" keycloak instance through Arquillian, rather than using mocks.

Maven build on master does not work

Sorry for this probably dumb question, but I'm not able to build the module using Maven. I tried to use:
mvn clean install -DskipTests -U

The problem is that Maven can not find the parent artifact of the pom:

    <parent>
        <groupId>org.keycloak.testsuite</groupId>
        <artifactId>integration-arquillian-tests</artifactId>
        <version>6.0.1</version>
    </parent>

I have configured the jboss-ga-repository, jboss-ga-plugin-repository, jboss-earlyaccess-repository, and jboss-earlyaccess-plugin-repository Maven repositories in my settings.xml. None of these repos contains that pom. I also searched the web for any other repo, but didn't find any repo containing that parent artifact.

How can I build your module? Maybe adding the description to the README would be good for others, too.

When using Keycloak as a WS-Fed identity broker, single logout leads to a NullPointerException

This can be tested with the following setup:

Client (WS-Fed)<---> Keycloak (Identity broker, WS-Fed) <---> Keycloak (Exernal IDP, WS-Fed)

With all elements set up correctly for Single Sign-on and logout, we can have a NullPointerException. The user is signed out of the external IDP, but neither from the identity broker nor its clients.

The cause of the NullPointerException must be verified and handled. The expected behaviour is that the user is signed out from the IDP and all of its clients.

The case should be tested with all combinations of Backchannel Logout and Handle Empty Action as wsignoutcleanup1.0 set to on/off.

Problem running the module (as it is) on 2.5.5 Final and 3.1.0 Final

I have problem running the current code as a module (at least not as easily as other example/small modules).

As it is within keycloak 2.5.5 Final

./bin/jboss-cli.sh --command="module add --name=com.quest.keycloak-wsfed --resources=./keycloak-wsfed-2.5.5.Final.jar --dependencies=org.keycloak.keycloak-server-spi,org.keycloak.keycloak-server-spi-private,org.keycloak.keycloak-saml-core,org.keycloak.keycloak-services,org.picketlink.picketlink-federation,org.picketlink.picketlink-common,org.apache.commons.commons-lang3,org.jboss.resteasy.resteasy-jaxrs"

Adding the registration line to standalone.xml

<providers>
    <provider>module:com.quest.keycloak-wsfed</provider>
</providers>

Get this error

10:14:15,379 ERROR [org.jboss.msc.service.fail] (ServerService Thread Pool -- 48) MSC000001: Failed to start service jboss.undertow.deployment.default-server.default-host./auth: org.jboss.msc.service.StartException in service jboss.undertow.deployment.default-server.default-host./auth: java.lang.RuntimeException: RESTEASY003325: Failed to construct public org.keycloak.services.resources.KeycloakApplication(javax.servlet.ServletContext,org.jboss.resteasy.core.Dispatcher)
	at org.wildfly.extension.undertow.deployment.UndertowDeploymentService$1.run(UndertowDeploymentService.java:85)
	at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
	at java.util.concurrent.FutureTask.run(FutureTask.java:266)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
	at java.lang.Thread.run(Thread.java:748)
	at org.jboss.threads.JBossThread.run(JBossThread.java:320)
Caused by: java.lang.RuntimeException: RESTEASY003325: Failed to construct public org.keycloak.services.resources.KeycloakApplication(javax.servlet.ServletContext,org.jboss.resteasy.core.Dispatcher)
	at org.jboss.resteasy.core.ConstructorInjectorImpl.construct(ConstructorInjectorImpl.java:162)
	at org.jboss.resteasy.spi.ResteasyProviderFactory.createProviderInstance(ResteasyProviderFactory.java:2209)
	at org.jboss.resteasy.spi.ResteasyDeployment.createApplication(ResteasyDeployment.java:299)
	at org.jboss.resteasy.spi.ResteasyDeployment.start(ResteasyDeployment.java:240)
	at org.jboss.resteasy.plugins.server.servlet.ServletContainerDispatcher.init(ServletContainerDispatcher.java:113)
	at org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher.init(HttpServletDispatcher.java:36)
	at io.undertow.servlet.core.LifecyleInterceptorInvocation.proceed(LifecyleInterceptorInvocation.java:117)
	at org.wildfly.extension.undertow.security.RunAsLifecycleInterceptor.init(RunAsLifecycleInterceptor.java:78)
	at io.undertow.servlet.core.LifecyleInterceptorInvocation.proceed(LifecyleInterceptorInvocation.java:103)
	at io.undertow.servlet.core.ManagedServlet$DefaultInstanceStrategy.start(ManagedServlet.java:231)
	at io.undertow.servlet.core.ManagedServlet.createServlet(ManagedServlet.java:132)
	at io.undertow.servlet.core.DeploymentManagerImpl.start(DeploymentManagerImpl.java:526)
	at org.wildfly.extension.undertow.deployment.UndertowDeploymentService.startContext(UndertowDeploymentService.java:101)
	at org.wildfly.extension.undertow.deployment.UndertowDeploymentService$1.run(UndertowDeploymentService.java:82)
	... 6 more
Caused by: java.lang.RuntimeException: org.jboss.modules.ModuleNotFoundException: com.quest.keycloak-wsfed:main
	at org.keycloak.provider.wildfly.ModuleProviderLoaderFactory.create(ModuleProviderLoaderFactory.java:44)
	at org.keycloak.provider.ProviderManager.<init>(ProviderManager.java:59)
	at org.keycloak.services.DefaultKeycloakSessionFactory.init(DefaultKeycloakSessionFactory.java:74)
	at org.keycloak.services.resources.KeycloakApplication.createSessionFactory(KeycloakApplication.java:313)
	at org.keycloak.services.resources.KeycloakApplication.<init>(KeycloakApplication.java:110)
	at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
	at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
	at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
	at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
	at org.jboss.resteasy.core.ConstructorInjectorImpl.construct(ConstructorInjectorImpl.java:150)
	... 19 more
Caused by: org.jboss.modules.ModuleNotFoundException: com.quest.keycloak-wsfed:main
	at org.jboss.modules.ModuleLoader.loadModule(ModuleLoader.java:223)
	at org.keycloak.provider.wildfly.ModuleProviderLoaderFactory.create(ModuleProviderLoaderFactory.java:40)
	... 28 more

I've also tried by moving dependencies to 3.1.0.Final & fixing what was crashing at the compile time then

./bin/jboss-cli.sh --command="module add --name=com.quest.keycloak-wsfed --resources=./keycloak-wsfed-3.1.0.Final.jar --dependencies=org.keycloak.keycloak-server-spi,org.keycloak.keycloak-server-spi-private,org.keycloak.keycloak-saml-core,org.keycloak.keycloak-services,org.picketlink.picketlink-federation,org.picketlink.picketlink-common,org.apache.commons.commons-lang3,org.jboss.resteasy.resteasy-jaxrs"

But I end with exactly the same error.

Single sign-out not working as expected

Scenario: we have an user that is logged in to several service providers (SPs).
We perform the logout on one SP. We would expect to see that Keycloak notifies the other SPs and performs the Single Sign-Out.
It looks like the logout is performed only on the SP where this operation was triggered.

Backchannel logout problem

I'm taking a shot in the dark here:
There is no such thing as "backchannel logout" in WSFED.
There simply can't be. Keycloak has zero knowledge of a client side session id and even if it had, the WSFED specs proposes no method to pass such an id to the client along with the wa=signoutcleanup1.0 request.
The only way to achieve a Keycloak initiated logout with a WSFED connected client is for Keycloak to ask the browser for a redirect. The browser will then send the logout request along with a client session cookie, enabling the client to close the session associated with the cookie.

Again, this is my understanding of the current implementation of the backchannel logout in keycloak-wsfed. I'd gladly hear anyone explain to me how things are supposed to work.

For the reference, here's the current keycloak wsfed code handling the backchannel logout in WSFedLoginProtocol.java:

URIBuilder builder = new URIBuilder(logoutUrl)
        .addParameter(WSFedConstants.WSFED_ACTION, WSFedConstants.WSFED_SIGNOUT_CLEANUP_ACTION)
        .addParameter(WSFedConstants.WSFED_REALM, client.getClientId());
HttpGet get = new HttpGet(builder.build());
HttpResponse response = httpClient.execute(get);

As you can see, no data related to the logged in user or to the client side session is passed along with the request.

Add support for client-scope mappers to the module

The module has been updated to 4.8.3.Final, but client scopes have been changed a lot since keycloak 3.4.3.Final, and are now not fully supported. This must be changed before a release can be done for the module.

How to obtain jars?

Where can we download jars for the new releases? Release page only have until version 3.4.3.
If we can not download, is there any build instructions to build the latest jars?

Keycloak 22+ Support Request

Hi,

I just installing Keycloak 22.0.3 on Ubuntu 22.04 with OpenJDK 19 and Maven 3.9, and try to configure it with this extension. It seems this extension can't be build anymore. May I know, do you have any intention to upgrade this extension to support newer version of Keycloak?

Thank you.

Cannot get Keycloak to correctly act as an Identity broker when WS-Fed is used as the protocol

The broker side of the code was tested with the following setup:

browser (requestor) <--> sharepoint (resource)<--> keycloak as identity broker <--> keycloak as IDP

This is actually a setup in the same pattern as in section 13.3 of the WS-Fed specification, which has the advantage of having expected messages to be described in appendix B of the same specification, allowing to compare what was going on.

However, I wasn't able to make the full example work. Going back to the section section 13.3 of the specification, at step 8 I'm getting a 302 instead of an POST (form) or an error page while using the "browser" first flow, and a nullpointer when using first broker login flow.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.