Thursday, 3 December 2015

Example Configuration - Local Account Linking

The Situation

In this example we will walk through connecting an SP which has a list of users in it, and an IdP which also have a list of users. The users in the SP’s datastore map to those in the IdP’s datastore one-to-one. The SP wishes to be able to allow their users to log in when they’re authenticated with the IdP. To link the accounts the SP desires that the user goes through a full, valid authentication flow on both the IdP and the SP once.

The Setup

To configure local account linking using the SAML2 authentication module, it’s necessary to configure some specific options inside the module and also inside the SP’s settings.

We’ll start by generating an SP using the common tasks wizard.

It is necessary to map the attributes which will be used to generate the data from the datastore - this is performed on the SP’s side. In this example, we will use the special *=* mapping, which means “for each attribute in the assertion, generate an attribute with that same name and value and store it in the generated session (and in the datastore if generating a local user account)”.

Finally as we’ll be using this SP in an authentication chain, as per the article SAML2 in chain authentication - The SAML2 Auth Module we must alter the Assertion Consumer Service for HTTP-Artifact and HTTP-POST binding types.

Now we’re ready to link our IdP and SP together using the ‘register remote [service/identity] provider’ common tasks in the appropriate provider. While you’re linking the SP to the IdP, you should set up some attributes from the IdP which will be included in the assertion which is sent to the SP - earlier we indicated that ‘uid’ would be our unique identifier, so let’s ensure we’re going to expose that, alongside a field we’ll recognise when we see it on the SP’s side - in the example here I’ve chosen the ‘mail’ attribute, and mapped it to a key/value in our assertion whose key is also ‘mail’. As the SP was configured with *=*, the ‘mail’ attribute in our assertion will be dynamically mapped to a ‘mail’ attribute in our SP’s datastore, as well as a session property named ‘mail’.

Finally on the IdP, let us generate a subject in the IdP’s datastore with a subject whose mail attribute is populated so that we will recognise it when we see it in the SP’s datastore later, and when we check the value of the federated session's properties.

Now the IdP is configured, it’s time to set up the authentication module proper.

Head back to the SP. Generate a new SAML2 authentication module. Here you’ll want to enter the meta alias and IdP Entity ID for your local SP and your remote IdP respectively. As we want the accounts to be persistently linked, we’ll allow for identifiers to be generated on the IdP by enabling Allow IdP to Create NameID and setting the NameID Format to urn:oasis:names:tc:SAML:2.0:named-format-persistent. To link the accounts, we need to specify the name of the authentication chain which will be used to identify the user in the SP's datastore. Enter the name of the chain in the Linking Authentication Chain field that will identify the user (this chain must include at least one first factor module - a module which results in the system knowing the local username of the user, for example the DataStore module). In this example we’ll call it ‘linkChain’. No other configuration settings are necessary to demonstrate the local account linking federation process.

We’ll need to generate the chain which will hold the authentication module. In this example, we will simply have the authentication module alone, and no other module following it.

Now let’s create ‘linkChain' - a secondary authentication chain which simply contains a DataStore module and nothing else.

Users attempting to access the SP will be prompted to log in to the IdP. If their accounts are already linked, they will then immediately be logged into the SP also. If their accounts aren't already linked, after successful IdP authentication they will be redirected to the SP's 'linkChain' authentication chain, and after successfully completing that chain their accounts will be linked and they will be logged in.

Example Configuration - Anonymous Session Generation With Federated Attributes

The situation

In this example we will walk through connecting an SP which has no attached datastore, and an IdP which also have a list of users. By logging into the IdP the user will generate an anonymous session on the SP where their session properties are filled with the attributes mapped from the IdP’s datastore attributes.

The Setup

To configure anonymous session generation using the SAML2 authentication module, it’s necessary to configure some specific options inside the module and also inside the SP’s settings.

We’ll start by generating an SP using the common tasks wizard.

It is necessary to map the attributes which will be used to generate the data from the datastore - this is performed on the SP’s side. In this example, we will use the special *=* mapping, which means “for each attribute in the assertion, generate an attribute with that same name and value in the generated anonymous session”.

Next, we need to enable the anonymous user account in the SP’s configuration. This should be done by entering ‘anonymous’ in the Transient User field.

Finally as we’ll be using this SP in an authentication chain, as per the article SAML2 in chain authentication - The SAML2 Auth Module we must alter the Assertion Consumer Service for HTTP-Artifact and HTTP-POST binding types.

Now we’re ready to link our IdP and SP together using the ‘register remote [service/identity] provider’ common tasks in the appropriate provider. While you’re linking the SP to the IdP, you should set up some attributes from the IdP which will be included in the assertion which is sent to the SP - let’s include a field we’ll recognise when we see it on the SP’s side - in the example here I’ve chosen the ‘mail’ attribute, and mapped it to a key/value in our assertion whose key is also ‘mail’. As the SP was configured with *=*, the ‘mail’ attribute in our assertion will be dynamically mapped to a ‘mail’ attribute in the session generated on the SP’s side.

Finally on the IdP, let us generate a subject in the IdP’s datastore with a subject whose mail attribute is populated so that we will recognise it when we check the value of the federated session's properties.

Now the IdP is configured, it’s time to set up the authentication module proper.

Head back to the SP. Firstly, let’s ensure that the user profile is ignored by dictating so to the settings:

Next, generate a new SAML2 authentication module. Here you’ll want to enter the meta alias and IdP Entity ID for your local SP and your remote IdP respectively. As we don’t want the accounts to be persistently linked, we’ll set the NameID Format to urn:oasis:names:tc:SAML:2.0:named-format-transient. No other configuration settings are necessary to demonstrate the anonymous session federation process.

Finally, we’ll need to generate the chain which will hold the authentication module. In this example, we will simply have the authentication module alone, and no other module following it.

Users attempting to access the SP will be prompted to log in to the IdP. Once authenticated they will be redirected back to the SP with a session belonging to the anonymous user, and the mapped attributes in their session's properties.

SAML2 in-chain authentication - The SAML2 Auth Module

The SAML2 authentication module is a new addition to OpenAM13. It comprises three new components which work together along with OpenAM’s SAML2 implementation to provide integrated SAML2 authentication to a standard OpenAM authentication chain. There are some limitations on the use of the new module - it supports HTTP-Artifact and HTTP-POST bindings and HTTP-Redirect and HTTP-POST request bindings. The new components are:

  • A new SAML2 authentication module
  • This is the authentication module that performs the bulk of the work. It handles identifying the user by sending them off to the remote identity provider, and - if appropriate - executing a sub-authentication chain which links the remote account to a local one.
  • A new assertion consumer endpoint
  • This assertion consumer endpoint differs slightly from the default OpenAM SAML2 endpoint, as it knows that it’s responsible for pushing the user agent back into the appropriate authentication chain. A SAML2 SP which utilises the authentication module must use the new assertion consumer endpoint.
  • A new post authentication plugin
  • This acts to enable IdP-initiated single logout support, and to configure and enable SP-initiated single logout.

If you’re familiar with the function of OpenAM 12’s SP implementation, the authentication module’s configuration page will be very familiar to you. The parameters filled in here can - for the most part - be thought of simply as query parameters which would be sent to the old spsssoinit endpoint. Each option is explained in terms of its function in relation to the SAML2 process both in the administrator UI and the OpenAM 13 documentation, as such they won’t be enumerated here. However, articles here will cover the options necessary to configure to be able to set up each example.

The SAML2 authentication module is a first factor module. That is, it results in the authentication modules following this module knowing the identity of the user in the local datastore the SAML2 module pointed to. This may be a newly Federated and generated user (see Dynamic Account Federation and Local Account Linking Account Federation examples) or an anonymous user (see article Anonymous Session Generation With Attribute Federation).

Finally, the SAML2 authentication module is the first module to contain the ability to perform a secondary authentication chain whose result acts as a component to this module. All this is explained in the Local Account Linking Federation example.

Example Configuration - Dynamic Account Federation

The situation

In this example we will walk through connecting an SP which has an attached datastore with no users in it, and an IdP which has a list of users. By logging into the IdP if the user does not exist in the SP’s datastore, it will generate a user in the datastore on the SP whose attributes will be populated by the mapped attributes from the IdP’s datastore for that user. Those attributes will also be available in the user’s session properties. If a login does already exist in the SP’s datastore these values will not be updated by this process, but new values read from the IdP’s datastore on each login will be propagated into the SP user’s session properties.

The Setup

This article will briefly describe the method to configure an SP which wishes to federate in their entirety accounts on the IdP’s side into a local datastore. To configure dynamic account federation using the SAML2 authentication module, it’s necessary to configure some specific options inside the module and also inside the SP’s settings.

We’ll start by generating an SP using the common tasks wizard.

It is necessary to map the attributes which will be used to generate the data from the datastore - this is performed on the SP’s side. In this example, we will use the special *=* mapping, which means “for each attribute in the assertion, generate an attribute with that same name and value and store it in the generated session (and in the datastore if generating a local user account)”.

Next, we need to enable auto-federation in the SP’s configuration. This should be done by selecting the ‘auto federation’ checkbox and supplying an attribute which acts as a unique identifier on the IdP’s side. As we’ll be federating the ‘uid’ attribute from our IdP (see the later steps of this article), we’ll enter ‘uid’ here.

Finally as we’ll be using this SP in an authentication chain, as per the article SAML2 in chain authentication - The SAML2 Auth Module we must alter the Assertion Consumer Service for HTTP-Artifact and HTTP-POST binding types.

Now we’re ready to link our IdP and SP together using the ‘register remote [service/identity] provider’ common tasks in the appropriate provider. While you’re linking the SP to the IdP, you should set up some attributes from the IdP which will be included in the assertion which is sent to the SP - earlier we indicated that ‘uid’ would be our unique identifier, so let’s ensure we’re going to expose that, alongside a field we’ll recognise when we see it on the SP’s side - in the example here I’ve chosen the ‘mail’ attribute, and mapped it to a key/value in our assertion whose key is also ‘mail’. As the SP was configured with *=*, the ‘mail’ attribute in our assertion will be dynamically mapped to a ‘mail’ attribute in our SP’s datastore, as well as a session property named ‘mail’.

Finally on the IdP, let us generate a subject in the IdP’s datastore with a subject whose mail attribute is populated so that we will recognise it when we see it in the SP’s datastore later, and when we check the value of the federated session's properties.

Now the IdP is configured, it’s time to set up the authentication module proper.

Head back to the SP. Firstly, dynamic account creation must be enabled in the realm’s authentication settings:

Next, generate a new SAML2 authentication module. Here you’ll want to enter the SP meta alias and IdP Entity ID for your local SP and your remote IdP respectively. As we want the accounts to be persistently linked, we’ll allow for identifiers to be generated on the IdP by enabling Allow IdP to Create NameID and setting the NameID Format to urn:oasis:names:tc:SAML:2.0:named-format-persistent. No other configuration settings are necessary to demonstrate the dynamic account federation process.

Finally, we’ll need to generate the chain which will hold the authentication module. In this example, we will simply have the authentication module alone, and no other module following it.

Users attempting to access the SP will be prompted to log in to the IdP. If their accounts are already linked, they will then immediately be logged into the SP also. If their accounts aren't already linked, after successful IdP authentication their account information will be federated over to the SP, and they will be redirected back to the SP as that newly federated user.

Enabling Single Log Out Support

The SAML2 Post Authentication Plugin (org.forgerock.openam.authentication.modules.saml2.SAML2PostAuthenticationPlugin) is an optional component which can be added to a chain which includes the SAML2 authentication module. It is responsible for configuring the session in such a way that it correctly responds to IdP-initiated single logout requests, and can additionally be configured to support SP-initiated single logout.

Supporting IdP-initiated single logout

By adding the SAML2 Post Authentication Plugin to your authentication chain, sessions which are logged in to your SP will be logged out when the IdP initiates logout (this may be a rather jarring experience for them, as they will simply be kicked out of the system upon the next action performed in the SP's service). There is no additional configuration required, and supporting SP-initiated single logout is not required if not desired.

Supporting SP-initiated single logout

By setting the Single Logout Enabled boolean inside the authentication module’s configuration to true, a request to log out from the SP will attempt to log out the IdP’s logged in session also. Upon successful logout from the IdP, the user will be redirected to the value provided in the Single Logout URL field - this value must be a fully-qualified URL. You may not support SP-initiated single logout without supporting IdP-initiated single logout.

Thursday, 7 November 2013

Getting started with IntelliJ, Mac OS X and Android 4.3 (18)

This should act as a quick getting-started guide to creating and editing Android apps on a Mac using IntelliJ.

Note: This article assumes that you have the latest version of Java installed through the normal Mac OS X installation method. This was written as Java version 1.6.0_51 was the most up-to-date version of Java released by Apple.

It also describes some solutions to frequently seen problems.

It will also demonstrate how to install HAX so we get a faster emulator.

Getting ready...

Before we start, download:

Install IntelliJ by copying the application over to your Applications/ folder

To install the Android SDK first cd to the directory you copied the sdk to, it should be called something like android-sdk-macosx. From there, cd tools and finally ./android. This will bring up the installation window, as shown below.

Select the files needed to complete the Android 4.3 (API 18) installation, and then let the SDK download them.

Once completed, it's time to get HAX installed so that we can run the resulting application at more than a snail's pace. To do this, run the appropriate installer from the site linked above, depending on which version of OS X you're using.

Creating the project...

Time to head into IntelliJ and get the environment set up so that we can develop.

Create New Project

Select Android | Application Module from the left, and give the project a name. Select the location to store the files, then click New... next to the Project SDK field. Locate the folder you downloaded the Android SDK to (the one which was originally named something like android-sdk-macosx) and select Choose. Finally, a pop-up should appear asking for you to select the appropriate Java JDK and Android SDK you wish to use. Select Java SDK 1.6 and Build target Android 4.3. You should end up with a New Project window that looks something like the following.

Press Next and allow for folders, etc. to be generated. Allow IntelliJ to generate the "Hello, World!" activity and selected Emulator as the Target Device. Do not worry that nothing is selected in the Prefer Android Virtual Device dropdown at this point.

You should now have a fully armed and operational battle station IDE, from which you can develop your application. So, let's set up the emulator so that we can see our new Android application in action. From the Run dropdown, select Edit Configurations... and create a new Android Application. Check that the correct Activity is selected to Launch (if following through using the default application this should simply be called MyActivity), and ensure that the Target Device is set to Emulator. Next, click the elipses (...) next to Prefer Android Virtual Device, and this will bring up a window entitled Android Virtual Device Manager. From here click New... and generate your Android device.

Give your device a name, then select the physical device that it will represent. You'll want to select as the Target the Android 4.3 - API Level 18, and as the CPU/ABI make sure you select Intel Atom(x86). Finally, it's best to give the machine 200MiB of SD Card space (see the list of common issues below). To make sure that the device starts up from scratch each time it's booted, ensure that the Snapshot checkbox is not ticked.

The finished window should look something like the following:

Finally, check that the virtual device you just generated is selected in the Prefer Android Virtual Device dropdown.

At this point you should be good to start up your emulator. Once the boot splash screen has left, and the lock screen is facing you, simply unlock the phone, and your new application should be staring you in the face.

Common Issues

Android error: INSTALL_FAILED_OLDER_SDK

Alter the uses-sdk element of your AndroidManifest.xml file. Ensure that its target and minimum are something appropriate, for example: <uses-sdk android:minSdkVersion="18" android:targetSdkVersion="18"/>

Android error: INSTALL_FAILED_INSUFFICIENT_STORAGE

Alter the AndroidManifest.xml file so that the manifest tag contains the attribute android:installLocation="preferExternal". You will also need to ensure that the emulated device within the Edit Endroid Virtual Device application has an SD Card with appropriate size installed, as shown below.

The emulator crashes immediately on boot with message "emulator64-x86 quit unexpectedly"

This occurs when the location to launch the emulation window isn't a value that the application understands. Generally when its been pulled across to a monitor that isn't the primary display. To resolve the issue, locate the file: ~/.android/avd/.avd/emulator-user.ini and alter the values window.x and window.y to both be 0.