Showing posts with label openid. Show all posts
Showing posts with label openid. Show all posts

Wednesday, 9 December 2015

First social login in Keycloak

One of the core Keycloak features is so called social brokering and identity provider brokering. Keycloak provides integration with the known social networks (Facebook, Google, Twitter, Github, StackOverflow, LinkedIn). You can also easily plug any other OpenID Connect, OAuth2 or SAML2 authentication server. When you click on particular social network (or identity server) button on login screen, Keycloak will use it to authenticate user and then redirect back to the application.

The social integration is available in Keycloak from it's early days. But we have also issues with so called First social login from it's early days. The term First login means that user authenticates to Keycloak for the first time through some particular social network (for example through Facebook).

Let's describe this in a bit more details. When Keycloak successfully authenticates user through social provider, there can be two situations:

  • There is already Keycloak user account linked with the authenticated social account. In this case, Keycloak will just authenticate as the existing user and redirect back to the application.
  • There is not yet existing Keycloak user account linked with the social account. This situation is more tricky. Usually you just want to register new account into Keycloak database, but what if there is existing Keycloak account with same email like the social account? Automatically link social account with existing Keycloak account is not very good option as there are possible security flaws related to that...
For the second case, we had lot of various related issues and lot of feedback and requirements from community and from our awesome jboss.org team. In the end, We changed the behaviour to be flexible and configurable through Authentication Flows SPI . This is available from Keycloak 1.7.0.CR1. Basically, you can configure the default set of authenticators, which allows you to change the behaviour according to your needs. It's also possible to implement your own Authenticator and adjust the behaviour exactly according your requirements.

The default behaviour for first social login is this:

  • User is optionally faced with the Review profile page where he can edit the claims (email, first name, last name and more) retrieved from social provider. By default, the page is displayed only when some of mandatory claims is missing (For example in case of Twitter, the page is always displayed as Twitter doesn't return email of user).
  • If there is no user with conflicting email in Keycloak database, user is automatically created and redirected back to the application.
  • Otherwise he needs to confirm that he wants to link his existing Keycloak account with the newly authenticated social account
  • If user choose to link accounts, he needs to either confirm linking by email verification, or he needs to re-authenticate and type his password (and optionally OTP). It depends on admin on how exactly he configures the authentication flow.

Here are some screenshots of how the typical first login with Facebook can look like. It includes review profile, confirming that user wants to link his Facebook account and verification of successful account linking by email verification.

For more details, see Keycloak documentation .

Additionally in 1.8 version, we have a plan for adding post-broker flow, which will allow additional verification after each login with social provider (For example OTP). So stay tuned.

Tuesday, 1 December 2015

Offline tokens in Keycloak

In Keycloak 1.6.1 We added support for offline tokens. This feature is described in OpenID Connect 1.0 specification and is useful for the applications, which needs to be able to do some actions on behalf of user, but in offline mode. Offline mode means that user is currently not logged in.

For example imagine Photo Album application, which needs to do periodic backup of saved user photos every day on midnight. This application can't never ensure that user is logged each midnight, but what it can do is:

  • When user authenticates to the application through Keycloak server, the application asks Keycloak server to return offline token instead of classic refresh token. The only thing application needs to do to request offline token is to add the parameter scope=offline_access during authentication request to Keycloak. Offline token is just special kind of refresh token, which never expires.
  • Photo Album application then saves the offline token in it's database
  • When user logout from the application, the session of user is invalidated. However offline token is still considered valid by Keycloak server.
  • On midnight, the application loads the offline token from it's database and send request to Keycloak to retrieve new access token. Even if user is offline, Keycloak will return access token corresponding to previously authenticated user. Application can use this access token to do the backup of photos on behalf of user and invoke any REST Backup service with the issued access token.

User is able to see and revoke any previously issued offline tokens in Keycloak Account Management application.

Also admin has possibility to see and revoke offline tokens of any particular user or eventually revoke all offline tokens issued to particular client application.

For more details, see Keycloak documentation and our Offline-access-app example, which is part of Keycloak example demo.

Monday, 12 October 2015

Authentication of clients with signed JWT

Until version 1.4 the confidential OpenID Connect client applications can be authenticated just with client ID and client secret. Client secret is shared between client application and Keycloak server and hence is known to both parties.

From the 1.5 version, we added support for authentication with private/public key pair. It's based on the RFC 7523 . The client authentication works in a way, that the client/adapter generates the Json Web Token (JWT) and signs it with his private key. The Keycloak server then verifies the signed JWT with the client's public key and authenticates client based on it.

The private key of client can be generated by Keycloak server and saved to keystore file on client side, or you can use existing private key of client and upload just certificate/public key to Keycloak server. In both cases, there is just client certificate and public key saved in Keycloak database.

There is increased security in this kind of client authentication in comparison to client secret, as the private key of client is not saved in Keycloak database and it's not sent over the network during client authentication.

More than that, we added support for pluggable client authentication. So if it's still not sufficient for you to authenticate your client with client secret or with signed JWT, you can implement and plug your own authenticator and configure it in admin console . See docs for more details.

Sunday, 7 June 2015

OpenShift UI Console authentication with Keycloak and OpenID Connect

Two months ago OpenShift team implemented OpenID Connect support for authentication in its UI Console. Thanks to this work it can be easily integrated with Keycloak using fairly simple configuration. In this blog post I'll take you through example configuration process.

For complete documentation about configuration of authentication in OpenShift please check official guide here

Requirements:

  • Keycloak 1.2.0.Final zip distribution
  • Environment with properly installed and configured Docker 1.6. Steps below were verified on Fedora 22


Part 1 - Keycloak installation and SSL setup

OpenShift v3 requires usage of HTTPS and also verifies that requests are signed with valid Certificate Authority. For the purpose of this blog we'll take the shortest possible route and quickly generate our own CA and self signed certs. In practice even when using self signed certificates there are number of good practices to follow which we'll not cover here. Be warned that what is described below is not a proper production setup :)

Create a directory which will be used for Keycloak installation, certs and OpenShift configuration:
$ export DEMO_DIR=/home/bdaw/kc_os_demo 
$ mkdir $DEMO_DIR
$ cd $DEMO_DIR
$ mkdir certs
$ mkdir openshift
Those few commands below should generate dummy CA and a keystore for Keycloak with properly signed certificate. "localhost" should be used as a domain name and "secret" as a password.

$ cd certs
$ keytool -genkey -alias localhost -keyalg RSA -keystore keycloak.jks -validity 10950
Enter keystore password: secret
Re-enter new password: secret
What is your first and last name?
 [Unknown]: localhost
What is the name of your organizational unit?
 [Unknown]: IT
What is the name of your organization?
 [Unknown]: ACME
What is the name of your City or Locality?
 [Unknown]: Eden
What is the name of your State or Province?
 [Unknown]: Heaven
What is the two-letter country code for this unit?
 [Unknown]: AA
Is CN=localhost, OU=IT, O=ACME, L=Eden, ST=Heaven, C=AA correct?
 [no]: yes
Enter key password for <localhost>
 (RETURN if same as keystore password): secret
Re-enter new password: secret 
$ keytool -certreq -alias localhost -keystore keycloak.jks > keycloak.careq
Enter keystore password: secret 
$ openssl genrsa -out rootCA.key 2048 

$ openssl req -x509 -new -nodes -key rootCA.key -days 1024 -out rootCA.pem
-----
Country Name (2 letter code) [XX]:AA
State or Province Name (full name) []:Heaven
Locality Name (eg, city) [Default City]:Eden
Organization Name (eg, company) [Default Company Ltd]:ACME
Organizational Unit Name (eg, section) []:IT
Common Name (eg, your name or your server's hostname) []:localhost
Email Address []:adam@acme.org 
$ openssl x509 -req -in keycloak.careq -CA rootCA.pem -CAkey rootCA.key -CAcreateserial -out keycloak-ca.crt -days 500
Signature ok
subject=/C=AA/ST=Heaven/L=Eden/O=ACME/OU=IT/CN=localhost
Getting CA Private Key 
$ keytool -import -keystore keycloak.jks -file rootCA.pem -alias root
Enter keystore password: secret
(...)
Trust this certificate? [no]:  yes
$ keytool -import -alias localhost -keystore keycloak.jks -file keycloak-ca.crt
Enter keystore password: secret
Certificate reply was installed in keystore 
$ ls
keycloak-ca.crt keycloak.careq keycloak.jks rootCA.key rootCA.pem rootCA.srl

Now unzip keycloak and copy created keystore
$ cd $DEMO_DIR
$ cp <dir_with_your_kc_zip>/keycloak-1.2.0.Final.zip .
$ unzip keycloak-1.2.0.Final
$ cp $DEMO_DIR/certs/keycloak.jks $DEMO_DIR/keycloak-1.2.0.Final/standalone/configuration/
To configure Keycloak to use SSL you need to follow procedure described in documentation. As you already have properly generated and signed certs in a keystore only changes in standalone.xml need to be applied.

Open $DEMO_DIR/keycloak-1.2.0.Final/standalone/configuration/standalone.xml in your favourite text editor and apply changes listed below:

To the security-realms element add:
<security-realm name="UndertowRealm">
        <server-identities>
            <ssl>
                <keystore path="keycloak.jks" relative-to="jboss.server.config.dir" keystore-password="secret" />
            </ssl>
        </server-identities>
    </security-realm>
Find the element <server name="default-server"> (it's a child element of <subsystem xmlns="urn:jboss:domain:undertow:1.2">) and add:
<https-listener name="https" socket-binding="https" security-realm="UndertowRealm"/>
Additionally we need to avoid conflict with default ports used by OpenShift. Find and adjust line below to change port 8080 to 8180 and 8443 to 8543:
<socket-binding name="http" port="${jboss.http.port:8180}"/>
<socket-binding name="https" port="${jboss.https.port:8543}"/>

Part II - Keycloak Configuration - Realm and OpenID Connect client for OpenShift

Start Keycloak and create new realm for openshift configuration
$ cd $DEMO_DIR/keycloak-1.2.0.Final/bin
$ ./standalone.sh
Go to https://localhost:8543/auth/admin

Log in with credentials admin/admin

In the top right corner click on "Add realm" link. Use "openshift" as a name and click "Save". You can play with configuration a bit if you want - allowing user registration and etc.



As a next step create "openshift" client

On the left side click on "Clients" and then "create" button. Fill in "openshift" for both client ID and name and "https://localhost:8443/*" for valid redirect URIs. Leave all other fields with default values.

Go to "Credentials" tab and copy value of "secret" field. It will be needed later in OpenShift configuration.



To verify authentication we'll need a sample user. On the left side click on "Users" and then "Add user". Use "test-user" as a username and click save. Then go to "Credentials" tab and set new password - for simplicity just use "password" as a value and submit with Enter :)

Voila! Now Keycloak should be properly configured to provide authentication for OpenShift. As you can see above biggest part of it was actually not related to OpenID Connect and OpenShift at all but to proper generation of certificates and SSL configuration... :)

Part III Openshift installation and configuration

There are few different ways to install OpenShift which are described either in official documentation or on github. Fabric8 can be used as well as it was described by Marko in one of previous posts

Simplest way to obtain needed parts to try out UI authentication is to use docker image and this is the setup we'll follow.

Start another terminal windows (first one should be occupied with running Keycloak server).
$ export DEMO_DIR=/home/bdaw/kc_os_demo 
$ sudo docker run -it --name "openshift-origin" --net=host --privileged -v /var/run/docker.sock:/var/run/docker.sock -v $DEMO_DIR:/opt/demo/ openshift/origin start master --write-config="/opt/demo/openshift/config"
It should create configuration files and exit.

Open $DEMO_DIR/openshift/config/master-config.yaml in your favorite text editor and adust configuration as below.

Find "oauthConfig" section and replace whole "identityProviders" section under it with content below:
   identityProviders:
  - name: keycloak
    challenge: false
    login: true
    provider:
      apiVersion: v1
      kind: OpenIDIdentityProvider
      ca: /opt/demo/certs/rootCA.pem
      clientID: openshift
      clientSecret: fdceb89f-3fa7-4b6d-8780-06074de5c62e
      claims:
        id:
        - sub
        preferredUsername:
        - preferred_username
        name:
        - name
        email:
        - email
      urls:
        authorize: https://localhost:8543/auth/realms/openshift/tokens/login
        token: https://localhost:8543/auth/realms/openshift/tokens/access/codes

Important thing to not forget - replace "clientSecret" value with the one which you found in Keycloak Admin UI.

As you can see "ca" is pointing to our dummy CA certificate (rootCA.pem). Alternatively you can remove this line and just add this cert to your system. OpenShift will validate against system wide ones by default.

Additionally locate the line starting with "logoutURL" and point it to Keycloak:

logoutURL: "https://localhost:8543/auth/realms/openshift/protocol/openid-connect/logout?redirect_uri=https://localhost:8443/console"

That is pretty much everything which is required on OpenShift side

In the master-config.yaml you can see to which IP address container is bind by checking "masterPublicURL" value. Obviously there are few other and probably better ways to determine it upfront... :). In my case it is "https://192.168.0.19:8443". This URL needs to be added to "openshift" client configuration in Keycloak as "Valid Redirect URI".



Now you can start OpenShift container again:
$ sudo docker rm openshift-origin
$ sudo docker run -it --name "openshift-origin" --net=host --privileged -v /var/run/docker.sock:/var/run/docker.sock -v $DEMO_DIR:/opt/demo/ openshift/origin start master --config="/opt/demo/openshift/config/master-config.yaml"
Go to "https://localhost:8443/console" and log in as "test-user" with password "password". Please note that you can also logout and this will properly get propagated to Keycloak.


In case of any issues you should hopefully see a meaningful error message logged either by OpenShift or by Keycloak server. Most common problems are related to network connectivity between OS and KC, certificate validation on the OS side and having proper redirect URI whitelisted in Keycloak. 

Huge thanks to Jordan Liggitt who implemented OpenID Connect support in OpenShift and Rob Cernich who contributed to it and initially tested it with Keycloak. You guys rock! :) 

Thursday, 21 May 2015

Securing Microservices

In a traditional multi-tiered architecture like the one shown in the picture below a server-side web tier deals with authenticating the user by calling out to a relational database or an LDAP server. An HTTP session is then created containing the required authentication and user details. The security context is propagated between the tiers within the application server so there's no need to re-authenticate the user.

With a microservice architecture the server-side web application is gone, instead we have HTML5 and mobile applications on the client side. The applications invoke multiple services, which may in turn call other services. In this architecture there's no longer a single layer that can deal with authentication and usually it's stateless as well so there's no HTTP session.

As microservices is all about having many smaller services each that deal with one distinct task the obvious solution to security is an authentication and authorization service. This is where Keycloak and OpenID Connect comes to the rescue. Keycloak provides the service you need to secure micro services.

The first step to securing micro services is authenticating the user. This is done by adding the Keycloak JavaScript adapter to your HTML5 application. For mobile applications there's a Keycloak Cordova adapter, but there's also native support though the AeroGear project.

In an HTML5 application you just need to add a login button and that's pretty much it. When the user clicks the login button the users browser is redirected to the login screen on the Keycloak server. The user then authenticates with the Keycloak server. As the authentication is done by the Keycloak server and not your application it's easy to add support for multi-factor authentication or social logins without having to change anything in your application.

Once the user is authenticated, Keycloak gives the application a token. The token contains details about the user as well as permissions the user has.

The second step in securing micro services is to secure them. Again, with Keycloak this is easy to do with our adapters. We've got JavaEE adapters, NodeJS adapters and are planning to adding more in the future. If we don't have an adapter it's also relatively easy to verify the tokens yourself. A token is basically just a signed JSON document and can be verified by the services itself or by invoking the Keycloak server.

If a service needs to invoke another service it can pass on the token it received, which will invoke the other service with the users permissions. Soon we'll add support for services to authenticate directly with Keycloak to be able to invoke other services with their own permissions, not just on behalf of users.

For more details about OpenID Connect you can look at the OpenID Connect website, but the nice thing is with Keycloak you don't really need to know the low level details so it's completely optional. As an alternative just go straight to the Keycloak website, download the server and adapters, and check out our documentation and many examples.