Contrail OAuth Authorization Server


Component description

Contrail OAuth Authorization Server provides end-point for OAuth Clients to obtain authorization for valid access tokens. These tokens can be used to obtain Contrail Resource using OAuth2 protocol.

Installation

Prerequisites

  • Apache Tomcat
  • MySQL
  • SAML 2.0 Identity Provider (Contrail package federation-id-prov)

Download and Extract

Download and extract contrail-oauth-as.tar.gz package. Deploy oauth-as.war webapp to Tomcat server.

Package structure:

/etc/contrail/contrail-oauth-as/
    * oauth-as.properties
    * saml-metadata.xml
/usr/share/contrail/contrail-oauth-as/
    * contrail-oauth-as-db-schema.sql
/var/lib/tomcat6/webapps/
    * oauth-as.war

Create the Database

  1. Create contrail-oauth-as database by importing the script /usr/share/contrail/contrail-oauth-as/contrail-oauth-as-db-schema.sql.
  2. Create database user and give him appropriate privileges on contrail-oauth-as database.
  3. Open persistence.xml file and enter database connection string, username and password of the database user.

Configure SAML metadata files

Local Metadata File

Open saml-metadata.xml file and enter metadata for SAML Service Provider and Identity Provider. The Contrail OAuth Authorization Server acts as a SAML Service Provider.

Identity Provider Metadata File

For SimpleSAMLphp (Contrail package federation-id-prov):
Open /usr/share/simplesamlphp-1.9.0/metadata/saml20-sp-remote.php file and add SAML metadata for Contrail OAuth Authorization Server which has a Service Provider role:

/* Service Provider: Contrail OAuth Authorization Server at contrail.xlab.si */
$metadata['https://contrail.xlab.si:8443/oauth-as/'] = array(
        'AssertionConsumerService' => array(
            array(
               'index' => 0,
               'isDefault' => TRUE,
               'Location' => 'https://contrail.xlab.si:8443/oauth-as/acs',
               'Binding' => 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST',
            )
        ),
        'SingleLogoutService' => 'https://contrail.xlab.si:8443/oauth-as/slo',
        );

Configuration Files

oauth-as.properties

File location: /etc/contrail/contrail-oauth-as/oauth-as.properties

# authorization code timeout in seconds
authzCode.timeout=300
# access token timeout in seconds
accessToken.timeout=86400

# path of the SAML metadata file
saml.metadataFile=/etc/contrail/contrail-oauth-as/saml-metadata.xml
# entity ID of local contrail-oauth-as (in the role of a Service Provider) in SAML metadata file
saml.SP.entityID=https://contrail.xlab.si:8443/oauth-as/
# entity ID of Identity Provider in SAML metadata file that should be used to authenticate users
saml.IdP.entityID=https://federation.contrail-idp.egi-cloud5.zam.kfa-juelich.de/simplesaml/saml2/idp/metadata.php
# SAML attributes mapping specified in JSON format {'AS attribute name' : 'IdP attribute name',...}
saml.attributesMapping={'uuid':'uuid'}

saml-metadata.xml

File location: /etc/contrail/contrail-oauth-as/saml-metadata.xml

<?xml version="1.0" encoding="UTF-8"?>
<EntitiesDescriptor
       xmlns="urn:oasis:names:tc:SAML:2.0:metadata"
       xsi:schemaLocation="urn:oasis:names:tc:SAML:2.0:metadata http://docs.oasis-open.org/security/saml/v2.0/saml-schema-metadata-2.0.xsd"
       cacheDuration="PT1H" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">

   <EntityDescriptor
           entityID="https://contrail.xlab.si:8443/oauth-as/">

       <SPSSODescriptor
               protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol">
           <AssertionConsumerService
                   index="0"
                   isDefault="true"
                   Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"
                   Location="https://contrail.xlab.si:8443/oauth-as/acs"
                   />
       </SPSSODescriptor>

       <Organization>
           <OrganizationName lang="en">XLAB</OrganizationName>
           <OrganizationDisplayName lang="en">XLAB Contrail Demo</OrganizationDisplayName>
           <OrganizationURL lang="en">http://www.xlab.si</OrganizationURL>
       </Organization>
   </EntityDescriptor>

   <EntityDescriptor
           entityID="https://federation.contrail-idp.egi-cloud5.zam.kfa-juelich.de/simplesaml/saml2/idp/metadata.php">

       <IDPSSODescriptor
               protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol">
           <SingleSignOnService
                   Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect"
                   Location="https://federation.contrail-idp.egi-cloud5.zam.kfa-juelich.de/simplesaml/saml2/idp/SSOService.php"
                   />
       </IDPSSODescriptor>
   </EntityDescriptor>

</EntitiesDescriptor>

persistence.xml

File location: /var/lib/tomcat6/webapps/oauth-as/WEB-INF/classes/META-INF/persistence.xml

<properties>
   <property name="eclipselink.cache.shared.default" value="false"/>
   <property name="eclipselink.target-database" value="MySQL"/>
   <property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver"/>
   <property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost/contrail_oauth_as"/>
   <property name="javax.persistence.jdbc.user" value="contrail"/>
   <property name="javax.persistence.jdbc.password" value="********"/>
</properties>

web.xml

File location: /var/lib/tomcat6/webapps/oauth-as/WEB-INF/web.xml

<context-param>
<param-name>conf-file</param-name>
<param-value>/etc/contrail/contrail-oauth-as/oauth-as.properties</param-value>
</context-param>

log4j.properties

File location: /var/lib/tomcat6/webapps/oauth-as/WEB-INF/classes/log4j.properties

log4j.rootCategory=ERROR, R
log4j.logger.org.ow2.contrail=TRACE

log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{ISO8601} %5p [%t] (%F:%L) - %m%n

log4j.appender.R=org.apache.log4j.RollingFileAppender
log4j.appender.R.File=/var/log/contrail/contrail-oauth-as.log
log4j.appender.R.MaxFileSize=30MB
log4j.appender.R.MaxBackupIndex=1
log4j.appender.R.layout=org.apache.log4j.PatternLayout
log4j.appender.R.layout.ConversionPattern=%d{ISO8601} %5p [%t] (%F:%L) - %m%n

Tomcat configuration

OAuth authorization server should be accessible only through secure (https) connection. Open Tomcat configuration file server.xml and set up SSL enabled connector which has clientAuth property set to 'want' (means that Tomcat requests a client certificate but doesn't fail if one isn't presented).

Example SSL connector configuration:
<Connector port="8443" protocol="HTTP/1.1" SSLEnabled="true"
   maxThreads="150" scheme="https" secure="true"
   clientAuth="want" sslProtocol="TLS"
   keystoreFile="/etc/tomcat6/contrail.xlab.si.jks" keystorePass="******"
   keyAlias="contrail.xlab.si"
   truststoreFile="/etc/tomcat6/cacerts.jks" truststorePass="******"
   ciphers="SSL_RSA_WITH_RC4_128_SHA" />

Administration

Registering OAuth Clients

OAuth Client Library

The  oauth-java-client  library provides utility classes that can be used by other Contrail modules to obtain access tokens and request delegated user certificates from the CA server. The module using the  oauth-java-client  library acts as a OAuth client in a OAuth protocol flow.

Obtaining an access token

The class  CCFlowClient  can be used to obtain an OAuth access token on behalf of a resource owner using the client credentials flow. The client credentials flow works without any user interaction so it is suitable for service to service interaction. But the prerequisite is that the user (resource owner) has given the consent in advance otherwise the access token request is refused.

Prerequisities:

  • keystore holding client private key/certificate signed by the Contrail CA
  • truststore holding Contrail CA certificate chain
  • client must be registered at the OAuth authorization server in advance (client id and client secret)
  • resource owner must give consent in advance that he allows client to access his protected resources

Following code snippets shows how to use  CCFlowClient :

Maven dependency:
<dependency>
   <groupId>org.ow2.contrail.common.oauth</groupId>
   <artifactId>oauth-java-client</artifactId>
   <version>0.1-SNAPSHOT</version>
</dependency>

CCFlowClient ccFlowClient = new CCFlowClient(tokenEndpointUri, keystoreFile, keystorePass,
        truststoreFile, truststorePass);
ccFlowClient.setClientId(clientId);
ccFlowClient.setClientSecret(clientSecret);
String accessToken = ccFlowClient.requestAccessToken(resourceOwner, scope);

Parameters:

  • tokenEndpointUri: URI of OAuth authorization server token endpoint
  • keystoreFile: key store file containing client private key and certificate signed by the Contrail CA
  • keystorePass: key store password
  • truststoreFile: trust store file containing Contrail CA certificate chain
  • truststorePass: trust store password
  • clientId: client id provided by the OAuth authorization server
  • clientSecret: client secret provided by the OAuth authorization server
  • resourceOwner: UUID of the resource owner on behalf which the access token should be requested
  • scope: scope of the access token, may be null

Example configuration:

client.id=oauth-java-client-demo
client.secret=somesecret
client.keystore.file=/etc/contrail/oauth-java-client-demo/oauth-java-client-demo.jks
client.keystore.pass=contrail
client.truststore.file=/etc/contrail/oauth-java-client-demo/cacerts.jks
client.truststore.pass=contrail
authzserver.accessTokenEndpointUri=https://contrail.xlab.si:8443/oauth-as/r/access_token/request

Complete example is available at svn+ssh://svn.forge.objectweb.org/svnroot/contrail/trunk/common/oauth/oauth-java-client-demo/client-cred-flow.

Retrieving a delegated user certificate

After the OAuth access token has been obtained, the client can request a delegated user certificate from the CA server which has an OAuth resource server role in this interaction. The CA server authenticates and authorizes the request based on the access token.

The oauth-java-client library provides a utility class  CertRetriever  for retrieving user certificate from the CA server. Following code snippet shows how to use  CertRetriever :

CertRetriever certRetriever = new CertRetriever(userCertEndpointUri, keystoreFile, keystorePass,
        truststoreFile, truststorePass);
X509Certificate cert = certRetriever.retrieveCert(accessToken);

Parameters:

  • userCertEndpointUri: URI of the CA Server user certificate endpoint
  • keystoreFile: key store file containing client private key and certificate signed by the Contrail CA
  • keystorePass: key store password
  • truststoreFile: trust store file containing Contrail CA certificate chain
  • truststorePass: trust store password
  • accessToken: OAuth access token

Example configuration:

client.keystore.file=/etc/contrail/oauth-java-client-demo/oauth-java-client-demo.jks
client.keystore.pass=contrail
client.truststore.file=/etc/contrail/oauth-java-client-demo/cacerts.jks
client.truststore.pass=contrail
caserver.userCertUri=https://contrail.xlab.si:8443/ca/o/delegateduser

Complete example is available at svn+ssh://svn.forge.objectweb.org/svnroot/contrail/trunk/common/oauth/oauth-java-client-demo, class ClientCredentialsFlowDemo.

Command Line Demo Tool

Oauth-java-client-demo provides a command line demo tool that can be used to obtain an access token and request a delegated user certificate. Configuration is located in the following file:
/etc/contrail/oauth-java-client-demo/oauth-java-client-demo.properties

The tool can be run from the oauth-java-client-demo project root using maven exec plugin. Usage:
ClientCredentialsFlowDemo getToken <user-UUID>
ClientCredentialsFlowDemo getCert <access-token>

Obtaining an access token:
mvn exec:java
 -Dexec.mainClass="org.ow2.contrail.common.oauth.demo.ClientCredentialsFlowDemo"
 -Dexec.args="getToken <user-UUID>"

Requesting a delegated user certificate:
mvn exec:java
 -Dexec.mainClass="org.ow2.contrail.common.oauth.demo.ClientCredentialsFlowDemo"
 -Dexec.args="getCert <access-token>"

Quick set-up

Follow these steps if you just want to see if the flow works. XLAB hosts demo CA server and demo OAuth2 AS. The flow descibed bellow should work as described.

Install contrail parent POM:
$ svn co svn://svn.forge.objectweb.org/svnroot/contrail/trunk/common/contrail-parent
$ mvn install

Checkout  oauth-java-client-demo :
$ svn co svn://svn.forge.objectweb.org/svnroot/contrail/trunk/common/oauth/oauth-java-client-demo/
$ mkdir -p /etc/contrail/oauth-java-client-demo/
$ cp ./src/main/resources/cacerts.jks /etc/contrail/
$ cp ./src/main/resources/oauth-java-client-demo.jks /etc/contrail/oauth-java-client-demo/
$ cp ./src/main/conf/oauth-java-client-demo.properties /etc/contrail/oauth-java-client-demo/
$ mvn clean compile

Ask for an oauth2 token for user  contrailuser :
$ mvn exec:java -Dexec.mainClass="org.ow2.contrail.common.oauth.demo.ClientCredentialsFlowDemo" -Dexec.args="getToken caa6e102-8ff0-400f-a120-23149326a936"

Output:
Requesting OAuth access token from the Authorisation Server https://contrail.xlab.si:8443/oauth-as/r/access_token/request on behalf of the user caa6e102-8ff0-400f-a120-23149326a936.
Received access token: 055e8fa9-aaf2-385d-bd07-a07bd443ac65

Ask for delegated certificate:
$ mvn exec:java -Dexec.mainClass="org.ow2.contrail.common.oauth.demo.ClientCredentialsFlowDemo" -Dexec.args="getCert 055e8fa9-aaf2-385d-bd07-a07bd443ac65"

Output:
Requesting delegated user certificate from the CA server https://contrail.xlab.si:8443/ca/o/delegateduser using access token 055e8fa9-aaf2-385d-bd07-a07bd443ac65.

Requesting delegated user certificate from the CA server https://contrail.xlab.si:8443/ca/o/delegateduser using access token 055e8fa9-aaf2-385d-bd07-a07bd443ac65.

Received user certificate:
  [0]         Version: 3
         SerialNumber: 1382011037020
             IssuerDN: DC=Slovenia,DC=Contrail,DC=ca,DC=users
          Start Date: Thu Oct 17 11:54:06 UTC 2013
          Final Date: Thu Oct 17 18:04:06 UTC 2013
            SubjectDN: DC=Slovenia,DC=Contrail,DC=ca,DC=users,CN=3,CN=contrailuser
          Public Key: RSA Public Key
            modulus: ab4d675445737492eecb451fe99ddee1a534d894c4222b924969155ac082a0dae8a1fd04b24ffef63d0081fb5ff976002e64b838ba21e11da360e555528fb1766276d29caf86e56ef65416b7eb4b4023076dc8ef3b27af50196cdae5050492b9ebf5dbb8cd7a5741773655022a2ddd2d32957a093082b27ee59cb56c46d1ad206d924164eb41b5328aedc3368642321699da1a13a50e46319737e4f1bd1d0583c72aa0f5200a9690b8b5326a6a6152737103144e0c19482b237f07c46591ce5b63019a771f11976ddab9f46534f6b20823cc64e4f8348bfa8345e124623d53a47afc469707412c36e81ea6832a7d9bf01a4e82506841ffe513d70cc8141a0881
   public exponent: 10001

  Signature Algorithm: SHA1WithRSAEncryption
            Signature: c1bc955dde0c736494a0560021faf49f9bb819b2

...

Admin REST API

Contrail OAuth Authorization Server provides admin REST API for managing organizations, clients, resource owner's trust, access tokens, monitoring protected resources accesses made with access tokens on behalf of the user...

Organizations

/organizations

GET

Returns a list of all registered organizations.

Sample request:
GET https://contrail.xlab.si:8443/oauth-as/admin/organizations

Sample response:
Status Code: 200 OK
Content-Type: application/json
[
   {
     "uri" : "/organizations/1",
     "id" : 1,
     "name" : "XLAB"
   }
]

POST

Creates a new organization.

Sample request:
POST https://contrail.xlab.si:8443/oauth-as/admin/organizations
Content-Type: application/json
{
  "name" : "XLAB"
}

Sample response:
Status Code: 201 Created
Location: https://contrail.xlab.si:8443/oauth-as/admin/organizations/1

/organizations/{orgId}

GET

Returns info about specified organization.

Sample request:
GET https://contrail.xlab.si:8443/oauth-as/admin/organizations/1

Sample response:
Status Code: 200 OK
Content-Type: application/json
{
  "uri" : "/organizations/1",
  "id" : 1,
  "name" : "XLAB",
  "clients" :
   [
      {
        "id" : 1,
        "name" : "federation-api",
        "uri" : "/clients/1"
      },
      {
        "id" : 4,
        "name" : "oauth-java-client-demo",
        "uri" : "/clients/4"
      }
   ]
}

PUT

Updates given attributes of specified organization.

Sample request:
POST https://contrail.xlab.si:8443/oauth-as/admin/organizations/1
Content-Type: application/json
{
  "name" : "XLAB"
}

Sample response:
Status Code: 204 No Content

DELETE

Deletes specified organization including all corresponding clients.

Sample request:
DELETE https://contrail.xlab.si:8443/oauth-as/admin/organizations/1

Sample response:
Status Code: 204 No Content

Clients

/organizations/{orgId}/clients

GET

Returns a list of all registered clients of specified organization.

Sample request:
GET https://contrail.xlab.si:8443/oauth-as/admin/organizations/1/clients

Sample response:
Status Code: 200 OK
Content-Type: application/json
[
   {
     "uri" : "/organizations/1/clients/1",
     "id" : 1,
     "client_id" : "oauth-java-client-demo",
     "name" : "oauth-java-client-demo"
   }
]

POST

Registers a new client of the specified organization.

Sample request:
POST https://contrail.xlab.si:8443/oauth-as/admin/organizations/1/clients
Content-Type: application/json
{
  'client_id' : 'oauth-java-client-demo',
  'name' : 'oauth-java-client-demo',
  'authorized_grant_types' : ['AUTHORIZATION_CODE', 'CLIENT_CREDENTIALS'],
  'callback_uri' : 'https://contrail.xlab.si:8444/oauth-demo/oauth2callback',
  'client_secret' : 'somesecret',
  'organization_id' : 1,
  'countries' : ['SI']
}

Sample response:
Status Code: 201 Created
Location: https://contrail.xlab.si:8443/oauth-as/admin/organizations/1/clients/1

/organizations/{orgId}/clients/{clientId}

GET

Returns info about specified client.

Sample request:
GET https://contrail.xlab.si:8443/oauth-as/admin/organizations/1/clients/1

Sample response:
Status Code: 200 OK
Content-Type: application/json
{
  "uri" : "/organizations/1/clients/1",
  "id" : 1,
  "client_id" : "oauth-java-client-demo",
  "name" : "oauth-java-client-demo",
  "callback_uri" : "https://contrail.xlab.si:8444/oauth-demo/oauth2callback",
  "organization_id" : 1,
  "authorized_grant_types" :
   [
     "AUTHORIZATION_CODE",
     "CLIENT_CREDENTIALS"
   ],
  "countries" :
   [
     "SI"
   ]
}

PUT

Updates given attributes of specified client.

Sample request:
PUT https://contrail.xlab.si:8443/oauth-as/admin/organizations/1/clients/1
Content-Type: application/json
{
  'countries' : ['SI', 'UK']
}

Sample response:
Status Code: 204 No Content

DELETE

Deletes specified client.

Sample request:
DELETE https://contrail.xlab.si:8443/oauth-as/admin/organizations/1/clients/1

Sample response:
Status Code: 204 No Content

Trust

/owners/{ownerUuid}/trust/organizations

GET

Returns a list of trust relationship between specified resource owner and organizations.

Sample request:
GET https://contrail.xlab.si:8443/oauth-as/admin/owners/caa6e102-8ff0-400f-a120-23149326a936/trust/organizations

Sample response:
Status Code: 200 OK
Content-Type: application/json
[
   {
     "trust_level" : "FULLY",
     "organization" :
      {
        "id" : 1,
        "name" : "XLAB",
        "uri" : "/organizations/1"
      },
     "uri" : "/owners/caa6e102-8ff0-400f-a120-23149326a936/trust/organizations/1"
   },
   {
     "trust_level" : "DENIED",
     "organization" :
      {
        "id" : 5,
        "name" : "CompanyX",
        "uri" : "/organizations/5"
      },
     "uri" : "/owners/caa6e102-8ff0-400f-a120-23149326a936/trust/organizations/5"
   }
]

POST

Adds a new trust relationship between specified resource owner and organization.

Sample request:
POST https://contrail.xlab.si:8443/oauth-as/admin/owners/caa6e102-8ff0-400f-a120-23149326a936/trust/organizations
Content-Type: application/json
{
  'organization_id' : 1,
  'trust_level' : 'FULLY'
}

Sample response:
Status Code: 201 Created
Location: https://contrail.xlab.si:8443/oauth-as/admin/owners/caa6e102-8ff0-400f-a120-23149326a936/trust/organizations/1

/owners/{ownerUuid}/trust/organizations/{orgId}

GET

Returns info about specified trust relationship.

Sample request:
GET https://contrail.xlab.si:8443/oauth-as/admin/owners/caa6e102-8ff0-400f-a120-23149326a936/trust/organizations/1

Sample response:
Status Code: 200 OK
Content-Type: application/json
{
  "trust_level" : "FULLY",
  "owner_uuid" : "caa6e102-8ff0-400f-a120-23149326a936",
  "organization" :
   {
     "id" : 1,
     "name" : "XLAB",
     "uri" : "/organizations/1"
   }
}

PUT

Updates given attributes (trust level) of specified trust relationship.

Sample request:
PUT https://contrail.xlab.si:8443/oauth-as/admin/owners/caa6e102-8ff0-400f-a120-23149326a936/trust/organizations/1
Content-Type: application/json
{
  "trust_level" : "DENIED",
}

Sample response:
Status Code: 204 No Content

DELETE

Deletes specified trust relationship.

Sample request:
DELETE https://contrail.xlab.si:8443/oauth-as/admin/owners/caa6e102-8ff0-400f-a120-23149326a936/trust/organizations/1

Sample response:
Status Code: 204 No Content

/owners/{ownerUuid}/trust/organizations/{orgId}/clients

GET

Returns a list of trust relationship between specified resource owner and clients.

Sample request:
GET https://contrail.xlab.si:8443/oauth-as/admin/owners/caa6e102-8ff0-400f-a120-23149326a936/trust/organizations/1/clients

Sample response:
Status Code: 200 OK
Content-Type: application/json
[
   {
     "trust_level" : "TRUSTED",
     "client" :
      {
        "id" : 1,
        "name" : "oauth-java-client-demo",
        "uri" : "/organizations/1/clients/1"
      },
     "uri" : "/owners/caa6e102-8ff0-400f-a120-23149326a936/trust/organizations/1/clients/1"
   }
]

POST

Adds a new trust relationship between specified resource owner and client.

Sample request:
POST https://contrail.xlab.si:8443/oauth-as/admin/owners/caa6e102-8ff0-400f-a120-23149326a936/trust/organizations/1/clients
Content-Type: application/json
{
  'client_id' : 1,
  'trust_level' : 'TRUSTED'
}

Sample response:
Status Code: 201 Created
Location: https://contrail.xlab.si:8443/oauth-as/admin/owners/caa6e102-8ff0-400f-a120-23149326a936/trust/organizations/1/clients/1

/owners/{ownerUuid}/trust/organizations/{orgId}/clients/{clientId}

GET

Returns info about specified trust relationship.

Sample request:
GET https://contrail.xlab.si:8443/oauth-as/admin/owners/caa6e102-8ff0-400f-a120-23149326a936/trust/organizations/1/clients/1

Sample response:
Status Code: 200 OK
Content-Type: application/json
{
  "trust_level" : "TRUSTED",
  "owner_uuid" : "caa6e102-8ff0-400f-a120-23149326a936",
  "client" :
   {
     "id" : 1,
     "name" : "oauth-java-client-demo",
     "uri" : "/organizations/1/clients/1",
     "organization_id" : 1
   }
}

PUT

Updates given attributes (trust level) of specified trust relationship.

Sample request:
PUT https://contrail.xlab.si:8443/oauth-as/admin/owners/caa6e102-8ff0-400f-a120-23149326a936/trust/organizations/1/clients/1
Content-Type: application/json
{
  "trust_level" : "NOT_TRUSTED",
}

Sample response:
Status Code: 204 No Content

DELETE

Deletes specified trust relationship.

Sample request:
DELETE https://contrail.xlab.si:8443/oauth-as/admin/owners/caa6e102-8ff0-400f-a120-23149326a936/trust/organizations/1/clients/1

Sample response:
Status Code: 204 No Content

/owners/{ownerUuid}/trust/countries

GET

Returns list of trusted/not trusted countries for the specified resource owner.

Sample request:
GET https://contrail.xlab.si:8443/oauth-as/admin/owners/caa6e102-8ff0-400f-a120-23149326a936/trust/countries

Sample response:
Status Code: 200 OK
Content-Type: application/json
[
   {
     "country_code" : "IT",
     "is_trusted" : true
   },
   {
     "country_code" : "SI",
     "is_trusted" : true
   }
]

PUT

Updates the list of trusted/not trusted countries.

Sample request:
PUT https://contrail.xlab.si:8443/oauth-as/admin/owners/caa6e102-8ff0-400f-a120-23149326a936/trust/countries
Content-Type: application/json
[
   {
     'country_code' : 'IT',
     'is_trusted' : true
   }
]

Sample response:
Status Code: 204 No Content

Resource Owners

/owners

GET

Returns list of all resource owners.

Sample request:
GET https://contrail.xlab.si:8443/oauth-as/admin/owners

Sample response:
Status Code: 200 OK
Content-Type: application/json
[
   {
     "id" : 1,
     "uuid" : "caa6e102-8ff0-400f-a120-23149326a936",
     "uri" : "/owners/caa6e102-8ff0-400f-a120-23149326a936",
     "owner_type" : "USER"
   }
]

POST

Adds a new resource owner.

Parameters:

  • uuid: UUID of the resource owner
  • owner_type: type of the resource owner (USER or SERVICE)
  • country_restriction (optional, false by default): enables or disables country restriction rules (trusted and untrusted countries)

Sample request:
POST https://contrail.xlab.si:8443/oauth-as/admin/owners
Content-Type: application/json
{
  'uuid' : 'caa6e102-8ff0-400f-a120-23149326a936',
  'owner_type' : 'USER',
  'country_restriction' : false
}

Sample response:
Status Code: 201 Created
Location: https://contrail.xlab.si:8443/oauth-as/admin/owners/caa6e102-8ff0-400f-a120-23149326a936

/owners/{ownerUuid}

GET

Returns info about specified resource owner.

Sample request:
GET https://contrail.xlab.si:8443/oauth-as/admin/owners/caa6e102-8ff0-400f-a120-23149326a936

Sample response:
Status Code: 200 OK
Content-Type: application/json
{
  "id" : 1,
  "uuid" : "caa6e102-8ff0-400f-a120-23149326a936",
  "uri" : "/owners/caa6e102-8ff0-400f-a120-23149326a936",
  "owner_type" : "USER",
  "country_restriction" : false,
  "organization_trust" : "/owners/caa6e102-8ff0-400f-a120-23149326a936/trust/organizations",
  "country_trust" : "/owners/caa6e102-8ff0-400f-a120-23149326a936/trust/countries"
}

/owners/{ownerUuid}/access_tokens

GET

Description:
Returns a list of all valid (not expired) access tokens corresponding to the specified resource owner (user).

Sample request:
GET https://contrail.xlab.si:8443/oauth-as/admin/owners/5a947f8c-83d3-4da0-a52c-d9436ae77bb5/access_tokens

Sample response:
[
   {
     "access_token" : "e94084e3-afa9-3a50-b5ea-2e45dfdd4392",
     "owner" : "5a947f8c-83d3-4da0-a52c-d9436ae77bb5",
     "client_id" : "oauth-java-client-demo",
     "expire_time" : "Tue Apr 23 11:10:09 CEST 2013",
     "uri" : "https://contrail.xlab.si:8443/oauth-as/admin/owners/5a947f8c-83d3-4da0-a52c-d9436ae77bb5/access_tokens/e94084e3-afa9-3a50-b5ea-2e45dfdd4392"
   }
]

/owners/{ownerUuid}/access_tokens/{token}

GET

Description:
Returns info about specified access token.

Sample request:
GET https://contrail.xlab.si:8443/oauth-as/admin/owners/5a947f8c-83d3-4da0-a52c-d9436ae77bb5/access_tokens/e94084e3-afa9-3a50-b5ea-2e45dfdd4392

Sample response:
{
  "access_token" : "e94084e3-afa9-3a50-b5ea-2e45dfdd4392",
  "owner" : "5a947f8c-83d3-4da0-a52c-d9436ae77bb5",
  "client_id" : "oauth-java-client-demo",
  "expire_time" : "Tue Apr 23 11:10:09 CEST 2013",
  "access_log" : "https://contrail.xlab.si:8443/oauth-as/admin/owners/5a947f8c-83d3-4da0-a52c-d9436ae77bb5/access_tokens/e94084e3-afa9-3a50-b5ea-2e45dfdd4392/access_log"
}

/owners/{ownerUuid}/access_tokens/{token}/access_log

GET

Description:
Returns list of all requests made with specified access token on behalf of the user (resource owner) to protected resources.

Sample request:
GET https://contrail.xlab.si:8443/oauth-as/admin/owners/5a947f8c-83d3-4da0-a52c-d9436ae77bb5/access_tokens/e94084e3-afa9-3a50-b5ea-2e45dfdd4392/access_log

Sample response:
[
   {
     "id" : 13,
     "access_token" : "e94084e3-afa9-3a50-b5ea-2e45dfdd4392",
     "timestamp" : "Mon Apr 22 11:20:27 CEST 2013",
     "bearer" : "CN=oauth-java-client-demo, O=XLAB, ST=Slovenia, C=SI",
     "resource_server" : "CN=ca-server, O=XLAB, ST=Slovenia, C=SI"
   }
]

/owners/{ownerUuid}/access_log

GET

Description:
Returns list of all accesses to protected resources made on behalf of the specified user (resource owner). For each access following data is given:

  • id: id of access log record
  • access_token: access token used to make request
  • timestamp: time of the request
  • bearer: the entity (the OAuth client) which made the request for protected resources on behalf of specified resource owner
  • resource_server: the entity (server) hosting the protected resources

Sample request:
GET https://contrail.xlab.si:8443/oauth-as/admin/owners/5a947f8c-83d3-4da0-a52c-d9436ae77bb5/access_log

Sample response:
[
   {
     "id" : 4,
     "access_token" : "602fee29-b42d-3938-be58-fed11dd3c1ea",
     "bearer" : "CN=oauth-java-client-demo, O=XLAB, ST=Slovenia, C=SI",
     "resource_server" : "CN=ca-server, O=XLAB, ST=Slovenia, C=SI",
     "timestamp" : "Mon Apr 15 10:21:16 CEST 2013"
   },
   {
     "id" : 7,
     "access_token" : "602fee29-b42d-3938-be58-fed11dd3c1ea",
     "bearer" : "CN=oauth-java-client-demo, O=XLAB, ST=Slovenia, C=SI",
     "resource_server" : "CN=ca-server, O=XLAB, ST=Slovenia, C=SI",
     "timestamp" : "Mon Apr 15 13:36:18 CEST 2013"
   },
      {
     "id" : 18,
     "access_token" : "dc663e1e-3842-3c35-a074-61c611d30cd4",
     "bearer" : "CN=federation-api, O=XLAB, ST=Slovenia, C=SI",
     "resource_server" : "CN=provider-accounting, O=XLAB, ST=Slovenia, C=SI",
     "timestamp" : "Mon May 6 11:29:05 CEST 2013"
   }
]

/owners/{ownerUuid}/accesses_per_rs

GET

Description:
Returns list of all accesses to protected resources made on behalf of the specified user (resource owner) grouped by resource servers. For each access following data is given:

  • resource server, the key of JSON map: the entity (server) hosting the protected resources
  • bearer: the entity (the OAuth client) which made the request for protected resources on behalf of specified resource owner
  • timestamp: time of the request

Sample request:
GET https://contrail.xlab.si:8443/oauth-as/admin/owners/5a947f8c-83d3-4da0-a52c-d9436ae77bb5/accesses_per_rs

Sample response:
{
  "CN=ca-server, O=XLAB, ST=Slovenia, C=SI" : [
      {
        "bearer" : "CN=oauth-java-client-demo, O=XLAB, ST=Slovenia, C=SI",
        "timestamp" : "Mon Apr 15 10:21:16 CEST 2013"
      },
      {
        "bearer" : "CN=oauth-java-client-demo, O=XLAB, ST=Slovenia, C=SI",
        "timestamp" : "Mon Apr 15 13:36:18 CEST 2013"
      }
   ],
  "CN=provider-accounting, O=XLAB, ST=Slovenia, C=SI" : [
      {
        "bearer" : "CN=federation-api, O=XLAB, ST=Slovenia, C=SI",
        "timestamp" : "Mon May 6 11:29:05 CEST 2013"
      }
   ]
}

Demo Scenario for Client Credentials Flow

Description

This demo demonstrates obtaining an access token by OAuth 2.0 client credentials flow for given user. Using that access token the client application then accesses protected resources on CA server on behalf of that user (resource owner), i.e. it requests delegated user certificate.

Detailed workflow:

  1. The application oauth-client-cred-flow-demo requests an OAuth access token using OAuth 2.0 client credentials flow
./oauth-client-cred-flow-demo.sh getToken <userUUID>

2. The AS checks if client is trusted (registered on the AS) by checking client ID and client secret it provided. If the client is not trusted the AS returns OAuth error response with error code unauthorized_client.

3. The AS checks if the client is authorized to get access token for the given user (resource owner). Because there is no user interaction in this workflow the user must have given his consent in advance.

4. The AS issues an access token and returns it to the client. Example response:
{
  "access_token":"2YotnFZFEjr1zCsicMWpAA",
  "token_type":"example",
  "expires_in":3600,
  "example_parameter":"example_value"
}

5. The client application oauth-client-cred-flow-demo requests a delegated user certificate from the CA server using the obtained access token. The client acts on behalf of the user.

./oauth-client-cred-flow-demo.sh getCert <access_token>

6. The CA server checks the validity of the access token by calling the AS validate_token method and authorizes the request - checks if the user is authorized to request the certificate

7. The CA server creates the certificate and returns it to the oauth-client-cred-flow-demo application
 

OAuth Authorization Server Info

Registering OAuth Client

Registering the Organization

First you have to register the organization the OAuth client belongs to:
POST https://contrail.xlab.si:8443/oauth-as/admin/organizations
Content-Type: application/json
{
  'name':'XLAB'
}

Response:
Status Code: 201 Created
Location: https://contrail.xlab.si:8443/oauth-as/admin/organizations/1

Get organization info:
GET https://contrail.xlab.si:8443/oauth-as/admin/organizations/1

Response:
{
  "uri" : "/organizations/1",
  "id" : 1,
  "name" : "XLAB",
  "clients" : "/organizations/1/clients"
}

Registering the Client

Register the OAuth client by calling:
POST https://contrail.xlab.si:8443/oauth-as/admin/organizations/1/clients
Content-Type: application/json
{
  'client_id' : 'oauth-cc-demo-client',
  'name' : 'oauth-cc-demo-client',
  'authorized_grant_types' : ['CLIENT_CREDENTIALS'],
  'client_secret' : 'somesecret',
  'countries' : ['SI']
}

Response:
Status Code: 201 Created
Location: https://contrail.xlab.si:8443/oauth-as/admin/organizations/1/clients/7

Get client info:
GET https://contrail.xlab.si:8443/oauth-as/admin/organizations/1/clients/7

Response:
{
  "uri" : "/organizations/1/clients/7",
  "id" : 7,
  "client_id" : "oauth-cc-demo-client",
  "name" : "oauth-cc-demo-client",
  "organization_id" : 1,
  "authorized_grant_types" :
   [
     "CLIENT_CREDENTIALS"
   ],
  "countries" :
   [
     "SI"
   ]
}

Demo Scenario 2

Overview

A client calls federation-api to get some accounting data for specific application. The federation-api must obtain an OAuth access token which enables it to request accounting data from the accounting component on behalf of the user - owner of the application.

Configuration

Federation-api

Runs on: 10.31.1.3

federation-api.cfg:

oauthClient.id=federation-api
oauthClient.secret=somesecret
oauthClient.keystore.file=/etc/contrail/federation-api/federation-api.jks
oauthClient.keystore.pass=contrail
oauthClient.truststore.file=/etc/contrail/federation-api/cacerts.jks
oauthClient.truststore.pass=contrail
oauthClient.accessTokenEndpointUri=https://contrail.xlab.si:8443/oauth-as/r/access_token/request
oauthDemo.protectedResourceUri=https://10.31.1.1:8443/accounting/accounting/test

Provider-accounting

Runs on: 10.31.1.1

accounting.cfg:

oauthFilter.tokenValidationService=https://contrail.xlab.si:8443/oauth-as/r/access_token/check
oauthFilter.keystoreFile=/etc/contrail/contrail-provider-accounting/contrail-provider-accounting.jks
oauthFilter.keystorePass=contrail
oauthFilter.truststoreFile=/etc/contrail/contrail-provider-accounting/cacerts.jks
oauthFilter.truststorePass=contrail

Contrail-oauth-as

Runs on: contrail.xlab.si

Prerequisites:

  • The federation-api has an OAuth client role in this interaction and must be trusted by the authorization server - it must be registered in the authorization server database.
  • The owner of the application for which accounting data is requested must give consent in advance that federation-api may access his accounting data. The user consent is recorded in the authorization server database.

Details

1. Federation-api receives following request:

GET http://10.31.1.3:8080/federation-api/applications/6ad216a6-0679-4f2f-9340-b00d12fe051e/accountingOAuthTest

2. Federation-api determines the owner of the application with specified UUID using the federation database. For that user it tries to obtain an OAuth access token which will enable the federation-api to request accounting data on behalf of that user. To request an access token it uses OAuth 2.0 client credentials flow that doesn't require any user interaction. The access token request is sent to the following url:

POST https://contrail.xlab.si:8443/oauth-as/r/access_token/request

grant_type=client_credentials&resource_owner=caa6e102-8ff0-400f-a120-23149326a936

3. The authorization server issues an access token if following conditions are met:

  • the client (federation-api) is trusted by the authorization server
  • the user has given the consent in advance that the client (federation-api) may access his accounting data

The authorization server returns access token response:

{
  "value" : "dc663e1e-3842-3c35-a074-61c611d30cd4",
  "expire_time" : "2013-05-14T16:29:55.000+0200",
  "expires_in" : 86400,
  "token_type" : "Bearer"
}

4. Federation-api receives the access token and stores it in its token cache noting the expiration time. For further requests the access token will be taken from the cache until the token expires.

5. Using the access token the federation-api calls the OAuth-protected accounting api and requests accounting data for given application. The access token is given in the authorization header.

6. Accounting component checks validity of the access token by calling authorization server's validation service:

POST https://contrail.xlab.si:8443/oauth-as/r/access_token/check

access_token=dc663e1e-3842-3c35-a074-61c611d30cd4&bearer_id=CN%3Dfederation-api%2C%20O%3DXLAB%2C%20ST%3DSlovenia%2C%20C%3DSI

7. The authorization server validates the token, logs the request in the access log and returns token info response:

{
  "access_token" : "dc663e1e-3842-3c35-a074-61c611d30cd4",
  "client_id" : "federation-api",
  "expire_time" : "2013-05-14T16:29:55.000+0200",
  "expires_in" : 86399,
  "token_type" : "Bearer",
  "owner_uuid" : "caa6e102-8ff0-400f-a120-23149326a936",
  "scope" : []
}

8. The accounting gets the token info response and in case the token is valid it returns requested accounting data.

9. Federation-api gets the accounting data and prepares response for the client.

AS Admin API Calls

List of Access Tokens

Request:
GET https://contrail.xlab.si:8443/oauth-as/admin/owners/caa6e102-8ff0-400f-a120-23149326a936/access_tokens

Response:
[
   {
     "access_token" : "dc663e1e-3842-3c35-a074-61c611d30cd4",
     "owner" : "caa6e102-8ff0-400f-a120-23149326a936",
     "client_id" : "federation-api",
     "expire_time" : "2013-05-14T16:29:55.000+0200",
     "uri" : "https://contrail.xlab.si:8443/oauth-as/admin/owners/caa6e102-8ff0-400f-a120-23149326a936/access_tokens/dc663e1e-3842-3c35-a074-61c611d30cd4"
   }
]

Access Token Info

Request:
GET https://contrail.xlab.si:8443/oauth-as/admin/owners/caa6e102-8ff0-400f-a120-23149326a936/access_tokens/dc663e1e-3842-3c35-a074-61c611d30cd4

Response:
{
  "access_token" : "dc663e1e-3842-3c35-a074-61c611d30cd4",
  "owner" : "caa6e102-8ff0-400f-a120-23149326a936",
  "client_id" : "federation-api",
  "expire_time" : "2013-05-14T16:29:55.000+0200",
  "access_log" : "https://contrail.xlab.si:8443/oauth-as/admin/owners/caa6e102-8ff0-400f-a120-23149326a936/access_tokens/dc663e1e-3842-3c35-a074-61c611d30cd4/access_log"
}

Access Log

Request:
GET https://contrail.xlab.si:8443/oauth-as/admin/owners/caa6e102-8ff0-400f-a120-23149326a936/access_log

Response:
[
   {
     "id" : 68,
     "access_token" : "dc663e1e-3842-3c35-a074-61c611d30cd4",
     "bearer" : "CN=federation-api, O=XLAB, ST=Slovenia, C=SI",
     "resource_server" : "CN=provider-accounting, O=XLAB, ST=Slovenia, C=SI",
     "timestamp" : "Mon May 13 16:29:55 CEST 2013"
   },
   {
     "id" : 70,
     "access_token" : "dc663e1e-3842-3c35-a074-61c611d30cd4",
     "bearer" : "CN=federation-api, O=XLAB, ST=Slovenia, C=SI",
     "resource_server" : "CN=provider-accounting, O=XLAB, ST=Slovenia, C=SI",
     "timestamp" : "Mon May 13 16:34:26 CEST 2013"
   }
]

Access Log per Resource Server

Request:
GET https://contrail.xlab.si:8443/oauth-as/admin/owners/caa6e102-8ff0-400f-a120-23149326a936/accesses_per_rs

Response:
{
  "CN=provider-accounting, O=XLAB, ST=Slovenia, C=SI" : [
      {
        "bearer" : "CN=federation-api, O=XLAB, ST=Slovenia, C=SI",
        "timestamp" : "Mon May 13 16:29:55 CEST 2013"
      },
      {
        "bearer" : "CN=federation-api, O=XLAB, ST=Slovenia, C=SI",
        "timestamp" : "Mon May 13 16:34:26 CEST 2013"
      }
   ]
}