Setting Up the UMA Example

This section describes tasks to set up AM as an authorization server:

  • Enabling cross-origin resource sharing (CORS) support in AM

  • Configuring AM as an authorization server

  • Registering UMA client profiles with AM

  • Setting up a resource owner (Alice) and requesting party (Bob)

Caution

The settings in this section are suggestions for this tutorial. They are not intended as instructions for setting up AM CORS support on a server in production.

If you need to accept all origins, by allowing the use of Access-Control-Allowed-Origin=*, do not allow Content-Type headers. Allowing the use of both types of headers exposes AM to cross-site request forgery (CSRF) attacks.

Enable CORS Support for AM

Before you start, prepare AM, IG, and the sample application as described in "Example Installation for This Guide".

If you use different settings for the sample application, see "Editing the Example to Match Custom Settings".

  1. Set up AM:

    1. Find the name of the AM session cookie:

      $ curl http://openam.example.com:8088/openam/json/serverinfo/* | jq .cookieName

      The rest of the steps in this procedure assume that you are using the default AM session cookie, iPlanetDirectoryPro. If not, substitute the value in the procedure.

    2. Create an OAuth 2.0 Authorization Server:

      1. Select  Services > Add a Service > OAuth2 Provider.

      2. Add a service with the default values.

    3. Configure an UMA Authorization Server:

      1. Select  Services > Add a Service > UMA Provider.

      2. Add a service with the default values.

    4. Add an OAuth 2.0 client for UMA protection:

      1. Select Applications > OAuth 2.0 > Clients.

      2. Add a client with these values:

        • Client ID: OpenIG

        • Client secret: password

        • Scope: uma_protection

      3. (From AM 6.5) On the Advanced tab, select the following option:

        • Grant Types: Resource Owner Password Credentials

    5. Add an OAuth 2.0 client for accessing protected resources:

      1. Select Applications > OAuth 2.0 > Clients.

      2. Add a client with these values:

        • Client ID: UmaClient

        • Client secret: password

        • Scope: openid

      3. (From AM 6.5) On the Advanced tab, select the following option:

        • Grant Types: Resource Owner Password Credentials and UMA

    6. Select Identities, and add an identity for a resource owner, with the following values:

      • ID: alice

      • Password: UMAexamp1e

    7. Select Identities, and add an identity for a requesting party, with the following values:

      • ID: bob

      • Password: UMAexamp1e

    8. Enable the CORS filter on AM:

      1. In a terminal window, retrieve an access_token from AM:

        $ mytoken=$(curl --request POST \
        --header "Accept-API-Version: resource=2.1" \
        --header "X-OpenAM-Username: amadmin" \
        --header "X-OpenAM-Password: password" \
        --header "Content-Type: application/json" \
        --data "{}"  \
        http://openam.example.com:8088/openam/json/authenticate | jq -r ".tokenId")
      2. Using the token retrieved in the previous step, enable the CORS filter on AM, by using the use the /global-config/services/CorsService REST endpoint:

        $ curl  \
          --request PUT \
          --header "Content-Type: application/json" \
          --header "iplanetDirectoryPro: $mytoken" http://openam.example.com:8088/openam/json/global-config/services/CorsService/configuration/CorsService \
          --data '{
             "acceptedMethods": [
               "POST",
               "GET",
               "PUT",
               "DELETE",
               "PATCH",
               "OPTIONS"
             ],
             "acceptedOrigins": [
               "http://app.example.com:8081",
               "http://openig.example.com:8080",
               "http://openam.example.com:8088/openam"
             ],
             "allowCredentials": true,
             "acceptedHeaders": [
               "Authorization",
               "Content-Type",
               "iPlanetDirectoryPro",
               "X-OpenAM-Username",
               "X-OpenAM-Password",
               "Accept",
               "Accept-Encoding",
               "Connection",
               "Content-Length",
               "Host",
               "Origin",
               "User-Agent",
               "Accept-Language",
               "Referer",
               "Dnt",
               "Accept-Api-Version",
               "If-None-Match",
               "Cookie",
               "X-Requested-With",
               "Cache-Control",
               "X-Password",
               "X-Username",
               "X-NoSession"
             ],
             "exposedHeaders": [
               "Access-Control-Allow-Origin",
               "Access-Control-Allow-Credentials",
               "Set-Cookie",
               "WWW-Authenticate"
             ],
             "maxAge": 600,
             "enabled": true,
             "allowCredentials": true
          }'
        
        {
         "_id": "CorsService",
         "_rev": "300529028",
         "maxAge": 600,
         "exposedHeaders": ["Access-Control-Allow-Origin", "Access-Control-Allow-Credentials", "WWW-Authenticate", "Set-Cookie"],
         "acceptedOrigins": ["http://openig.example.com:8080", "http://app.example.com:8081", "http://openam.example.com:8088/openam"],
         "acceptedMethods": ["DELETE", "POST", "GET", "OPTIONS", "PUT", "PATCH"],
         "acceptedHeaders": ["Cookie", "Origin", "X-Username", "Accept", "X-Requested-With", "Connection", "User-Agent", "Referer", "Host", "Dnt", "X-NoSession", "Accept-Encoding", "iPlanetDirectoryPro", "If-None-Match", "Authorization", "Cache-Control", "X-OpenAM-Username", "X-Password", "Accept-Language", "Content-Length", "X-OpenAM-Password", "Accept-Api-Version", "Content-Type"],
          "enabled": true,
          "allowCredentials": true,
          "_type": {
            "_id": "CorsService",
            "name": "CORS Service",
            "collection": true
          }
        }

        Tip

        To delete the CORS configuration and create another, first run the following command:

        $ curl \
         --request DELETE \
         --header "X-Requested-With: XMLHttpRequest" \
         --header "iplanetDirectoryPro: $mytoken" \
         http://openam.example.com:8088/openam/json/global-config/services/CorsService/CorsService/configuration/CorsService
  2. Set up IG as an UMA resource server:

    1. Add the following route to IG, to serve .css and other static resources for the sample application:

      $HOME/.openig/config/routes/static-resources.json
      %appdata%\OpenIG\config\routes\static-resources.json
      {
        "name" : "sampleapp_resources",
        "baseURI" : "http://app.example.com:8081",
        "condition": "${matches(request.uri.path,'^/css')}",
        "handler": "ReverseProxyHandler"
      }
    2. Add the following route to IG:

      $HOME/.openig/config/admin.json
      %appdata%\OpenIG\config\admin.json

      {
        "prefix": "openig",
        "connectors": [
          { "port" : 8080 }
        ],
        "heap": [
          {
            "name": "ClientHandler",
            "type": "ClientHandler"
          },
          {
            "name": "ApiProtectionFilter",
            "type": "CorsFilter",
            "config": {
              "policies": [
                {
                  "origins": [ "http://app.example.com:8081" ],
                  "acceptedMethods": [ "GET", "POST", "DELETE" ],
                  "acceptedHeaders": [ "Content-Type" ]
                }
              ]
            }
          }
        ]
      }
      {
        "prefix": "openig",
        "heap": [
          {
            "name": "ClientHandler",
            "type": "ClientHandler"
          },
          {
            "name": "ApiProtectionFilter",
            "type": "CorsFilter",
            "config": {
              "policies": [
                {
                  "origins": [ "http://app.example.com:8081" ],
                  "acceptedMethods": [ "GET", "POST", "DELETE" ],
                  "acceptedHeaders": [ "Content-Type" ]
                }
              ]
            }
          }
        ]
      }

      Notice the following feature of the route:

      • The default ApiProtectionFilter is overridden by the CorsFilter, which allows requests from the origin http://app.example.com:8081. For information, see "AdminHttpApplication (admin.json)".

    3. Add the following route to IG:

      $HOME/.openig/config/routes/00-uma.json
      %appdata%\OpenIG\config\routes\00-uma.json
      {
        "name": "00-uma",
        "condition": "${request.uri.host == 'app.example.com'}",
        "heap": [
          {
            "name": "UmaService",
            "type": "UmaService",
            "config": {
              "protectionApiHandler": "ClientHandler",
              "wellKnownEndpoint": "http://openam.example.com:8088/openam/uma/.well-known/uma2-configuration",
              "resources": [
                {
                  "comment": "Protects all resources matching the following pattern.",
                  "pattern": ".*",
                  "actions": [
                    {
                      "scopes": [
                        "#read"
                      ],
                      "condition": "${request.method == 'GET'}"
                    },
                    {
                      "scopes": [
                        "#create"
                      ],
                      "condition": "${request.method == 'POST'}"
                    }
                  ]
                }
              ]
            }
          }
        ],
        "handler": {
          "type": "Chain",
          "config": {
            "filters": [
              {
                "type": "CorsFilter",
                "config": {
                  "policies": [
                    {
                      "origins": [ "http://app.example.com:8081" ],
                      "acceptedMethods": [ "GET" ],
                      "acceptedHeaders": [ "Authorization" ],
                      "exposedHeaders": [ "WWW-Authenticate" ],
                      "allowCredentials": true
                    }
                  ]
                }
              },
              {
                "type": "UmaFilter",
                "config": {
                  "protectionApiHandler": "ClientHandler",
                  "umaService": "UmaService"
                }
              }
            ],
            "handler": "ReverseProxyHandler"
          }
        }
      }
      

      Notice the following features of the route:

      • The route matches requests from app.example.com.

      • The UmaService describes the resources that a resource owner can share, using AM as the authorization server. It provides a REST API to manage sharing of resource sets.

      • The CorsFilter defines the policy for cross-origin requests, listing the methods and headers that the request can use, the headers that are exposed to the frontend JavaScript code, and whether the request can use credentials.

      • The UmaFilter manages requesting party access to protected resources, using the UmaService. Protected resources are on the sample application, which responds to requests on port 8081.

    4. Restart IG to reload the configuration.

  3. Test the setup:

    1. If necessary, log out of AM, and then go to http://app.example.com:8081/uma/.

    2. Share resources:

      1. Select Alice shares resources.

      2. On Alice's page, select Share with Bob. The following items are displayed:

        • The PAT that Alice receives from AM.

        • The metadata for the resource set that Alice registers through IG.

        • The result of Alice authenticating with AM in order to create a policy.

        • The successful result when Alice configures the authorization policy attached to the shared resource.

        Tip

        If the step fails, run the following command to get an access token for Alice:

        $ curl -X POST \
        -H "Cache-Control: no-cache" \
        -H "Content-Type: application/x-www-form-urlencoded" \
        -d 'grant_type=password&scope=uma_protection&username=alice&password=UMAexamp1e&client_id=OpenIG&client_secret=password' \
        http://openam.example.com:8088/openam/oauth2/access_token
        
        {"access_token":"AQI...QAA*","scope":"uma_protection","token_type":"Bearer","expires_in":3599}

        If you fail to get an access token, check that AM is configured as described in "Setting Up the UMA Example". If you continue to have problems, make sure that your IG configuration matches that shown when you are running the test on http://app.example.com:8081/uma/.

    3. Access resources:

      1. Go back to the first page, and select Bob accesses resources.

      2. On Bob's page, select Get Alice's resources. The following items are displayed:

        • The WWW-Authenticate Header.

        • The OpenID Connect Token that Bob gets to obtain the RPT.

        • The RPT that Bob gets in order to request the resource again.

        • The final response containing the body of the resource.

Read a different version of :