Quantcast
Channel: ATeam Chronicles
Viewing all 95 articles
Browse latest View live

Social Federation with OAM Mobile & Social in Native iOS Applications

$
0
0

Introduction

I’ve already posted an article about Social Federation with Mobile & Social (M&S) for web applications protected by Oracle Access Manager (OAM), showing users being authenticated against social network providers, like Google and Linkedin.
My coworker Chris Johnson also blogged about using Mobile & Social in a native iOS application. In his post, user authentication happens against OAM identity store.

In this post, we have both worlds. We’re going to explore how to implement user authentication against social network providers via OAM’s M&S component in a native iOS application. I will show the necessary configuration in the social network provider, in M&S and how to setup the Xcode project for M&S SDK as well as the necessary coding.

However, before going any further, I’d like to explore why we’d want to use M&S in the first place and not simply just wire up our iOS application directly to the social network provider.

There’s an interesting saying that you can solve virtually any communication problem between two parties by having something in between them. In our case, not having M&S in between the iOS application and the social network provider is not the end of the world, as you can totally rely on the provider’s APIs. Having M&S in the middle, however, brings a good advantage in terms of deployment speed and helps shielding iOS developers from the requirements of dealing with the provider’s API. If today your iOS applications use Google for authenticating users, tomorrow you can add Facebook, Linkedin or Twitter without changing a single line of code in your applications. Notice I said “add”, i.e., your mobile applications can offer its users the possibility of authenticating against multiple identity providers without any code changes.

Another subtle aspect is that the client application can (if configured) end up with two access tokens: one OAuth Access Token issued by the IdP (Identity Provider) and one JSON Web Token (JWT) issued by OAM Mobile & Social. If your application needs to consume protected resources from both the social network provider and from Mobile & Social, this is a great benefit.

At a high-level, the use case scenario being explored here is depicted in the following diagram. Notice OAM M&S intermediating the interaction between the iOS App and the IdP. Once the iOS application starts, it contacts M&S to start the authentication process (step 1). M&S sends back a view displaying one or more authentication options to the application (step 2). The user picks up one provider option, signaling M&S to authenticate with that provider (step 3). M&S relays the authentication request to the provider (step 4), who sends its own login screen (followed by consent screen) back to the application (step 5). Once the end user provides her credentials and consent (step 5), the IdP returns an access token to OAM M&S (step 6), who, in turn, adds its own JWT before returning both to the iOS application (step 7).

 

Authentication Process

Authentication Process

The following sections cover in detail the necessary configuration for implementing the use case scenario.

 

Main Article

Internet Identity Provider

In this post, the term Internet Identity Provider is interchangeably used as Social Network Provider or just Identity Provider.

For the purposes of this post, I am going to show the necessary configuration having Google as the Identity Provider using the OpenID Connect protocol, which is essentially the OAuth 2.0 protocol. Notice that OpenID Connect for Google is not OOTB (Out Of The Box) available in M&S 11.1.2.2. The necessary configuration is covered in the Mobile & Social section.

The steps for creating the necessary footprint in Google are the very same ones presented in my previous post about Social Federation. I repeat them here for your convenience.

1 – Create a Project

Go to Google Developer’s Console (https://console.developers.google.com) and create a project. Give it any name you wish. Within your newly created project, there are only two links you care about: Credentials and Consent Screen, as shown below:

Google Developers Console Dashboard

Google Developers Console Dashboard

2 – Create a Web Client Application

Within the project, create Client Credentials for a Web Application. From Google’s perspective, the client is M&S, not the iOS application. Thus, it is a web application.

Web Application Credentials

Web Application Credentials

You’re going to use CLIENT ID (1) and CLIENT SECRET (2) when configuring Google Social Identity Provider in M&S.

Do notice the REDIRECT URIS (3). For M&S, it must be http://<OAM_SERVER_HOST>:<OAM_SERVER_PORT>/oic_rp/return.

 

3 – Configure a Consent Screen for the Application

The values entered in the Consent Screen have no bearings on any M&S configuration. In Google’s case, there’s one consent screen per project and it’s always presented whenever there’s an incoming request with your application-specific CLIENT ID.

Consent Screen

Consent Screen

Notice:

1. PRODUCT NAME. The value is used by the consent screen at runtime, as shown below. You can enter any value and it doesn’t need to match anything in M&S configuration.

2. PRODUCT LOGO is the little icon that gets displayed right next to the user’s picture.

 

Consent Screen at Runtime

Consent Screen at Runtime

 

Mobile & Social

The necessary configuration in M&S is all done using the two links marked below in OAM’s main screen:

 

OAM M&S

OAM M&S

1 – Create a custom Internet Identity Provider for Google OpenID Connect

As of OAM 11.1.2.2, there’s no OOTB (Out Of The Box) Social Provider for Google OpenID Connect.

This is how we create one: Under the Social Identity link, create a new Internet Identity Provider for the oauth protocol using the values as seen (except for Name, Description, Consumer Key and Consumer Secret) in the following screen shot:

 

Google OpenID Connect (OAuth 2) Internet Identity Provider

Google OpenID Connect (OAuth 2) Internet Identity Provider

Notice:

1. Arrows 1 and 2 refer to the CLIENT ID and CLIENT SECRET obtained in Google Developer’s Console. Refer to step 2 of the previous section.

As for the user attributes to be returned by Google Internet Identity Provider, rolling down the screen, here’s how they’re defined:

 

Google OpenID Connect (OAuth 2) Internet Identity Provider (cont'd)

Google OpenID Connect (OAuth 2) Internet Identity Provider (cont’d)

2 – Create an Application Profile for the iOS application in both Mobile Services and Social Identity.

The application profiles to be created are required to be given the same name under Mobile Services and Social Identity. In our sample, the name is ShowRoomiPhone.

The Mobile Services Application Profile deals with registration configuration for the mobile application as well as how M&S interacts with the application, whether via an embedded or external browser.

 

Mobile Services Application Profile

Mobile Services Application Profile

 

In this first section of our Mobile Services Application Profile, the values are the default ones (except for Name and Description). Time allowing, I will come back on a future post talking about these settings. For the purposes of this post, we don’t need to change any of them.

 

Mobile Services Application Profile (cont'd)

Mobile Services Application Profile (cont’d)

 

In the second section of the screen it’s important to call out two fields:

1. Internet Identity Services Webview: this defines how the screens of the Social Network Provider are “embedded” in your application. Embedded browser basically means a UIWebView for iOS-based applications.

2. Apple iOS Bundle ID: this is your iOS application identifier in M&S. It MUST match your iOS application Bundle Identifier.

 

iOS Application Bundle Identifier

iOS Application Bundle Identifier

 

The Social Identity Application Profile defines everything else for the purposes of authentication and how M&S returns data to the mobile application, specifically:

a. Authentication types supported;

b. Whether and how user registration is necessary;

c. User Profile and Authentication service endpoints;

d. Application Profile Properties;

e. The Social Providers supported by the application and their attribute mappings;

We can see these in the following 2 screens:

 

Social Identity Application Profile

Social Identity Application Profile

 

Notice:

1. Mobile Application Return URL (app://show.room.iphone) MUST match a URL type in the iOS application (more on this shortly when I talk about the iOS application). The URL type is used by for registering the application into the iOS device so it can be invoked by other applications. It is used by M&S to return Internet Identity authentication data to the iOS application.

   TIP: Do NOT use http as the URL protocol (or URL Scheme), because that would instruct M&S to look for a real HTTP endpoint, which is not the case for a mobile application. Here I use “app” as the URL Scheme.

2. User Registration is not mandatory for mobile applications and can be disabled.

3. Make sure Authentication Service Endpoint is set to /internetidentityauthentication. This delegates authentication to the Social Identity providers defined at the bottom of the screen.

4. In Application Profile Properties, oic.app.idp.oauth.token = true makes M&S returning the IdP OAuth Access Token to the mobile application.

5. oic.app.user.token = true would make M&S returning a JWT to the mobile application. I’ve noticed this is actually not necessary. M&S will return its JWT anyways.

 

Social Identity Application Profile (cont'd)

Social Identity Application Profile (cont’d)

 

The second part of the screen, as just shown, defines the available attributes to the application profile and their mappings with the Identity Providers. Together, these mean that only the mapped attributes are going to be available to the M&S Social Identity Application Profile.

Notice:

Linkedin is also checked. This is ALL you need to do for allowing authentication against multiple Identity Providers. At runtime, M&S sends a view like the following to your iOS application:

 

M&S Login Screen

M&S Login Screen

 

3 – Configure (or create a new one) the Mobile Service Domain and add the Mobile Service Application Profile to it.

A Service Domain defines the association between Mobile Service Application Profiles, their Service Profiles as well as (optionally) the protection levels for those services. The name of the service domain is typically used by client applications using the M&S SDK for initializing the APIs and later on interacting with M&S server. In my sample, I simply reuse the OOTB default MobileServiceDomain.

 

Mobile Service Domain Application Profiles

Mobile Service Domain Application Profiles

Notice:

1. Type MUST be Mobile Application;

2. Authentication Scheme MUST be Internet Identity Authentication;

3. ShowRoomiPhone Application Profile has been added;

4. On Service Profiles tab, make sure Authentication Service is set to InternetIdentityAuthentication, as in the following screen shot. This is essential when the iOS application tries to register itself in M&S at runtime.

 

Mobile Service Domain Service Profile

Mobile Service Domain Service Profile

 

The iOS Application

The sample iOS application is really just a test application. All it does, for the time being, is writing the tokens it gets back from M&S to the output. In a future post, I will show how we can use these tokens for making secure calls to REST-based services.

1. Download M&S iOS SDK from this link and extract it to your local disk..

2. Add the SDK libraries to your Xcode project.

Drag the libIDMMobileSDK.a file, PublicHeaders and PublicResources folders and drop them right over your application project in Xcode. This will get your project automatically configured with M&S SDK.

Adding M&S SDK libraries to Xcode project

Adding M&S SDK libraries to Xcode project

 

This is how your project should look like after adding those libraries:

 

XCode Project with M&S SDK libraries

XCode Project with M&S SDK libraries

Notice:

M&S SDK depends on CoreLocation, Security and SystemConfiguration frameworks. Make sure they’re also included in your project.

 

Required Frameworks

Required Frameworks

 

3. In your project Build Settings, add the following flags to Other Linker Flags in the Linking section: -ObjC -all-load. Explanations here.

 

Linker Flags

Linker Flags

 

4. Add a URL type to your iOS application. This is done in the Info section of your application project in XCode. The URL type is composed of <URL Scheme>://<Identifier> and MUST match Mobile Application Return URL in M&S Social Identity Application Profile. In my example, <URL Scheme> value is app, and <Identifier> value is show.room.iphone.

 

Application URL Type

Application URL Type

Again, this URL is used by M&S to callback the iOS application. At runtime, we can verify it by looking at this TCP stream sample captured with the Wireshark sniffer tool. Notice the URL Type in the response’s Location header.

 

GET /oic_rp/return?state=3ec418cdec53976fb110b076faef4c7065a11792&code=4/VSYXo_7v7rslAf6rdS3T7kVBjLifNIWnCcvKgDGD-vI.gtM2tGFEacYUEnp6UAPFm0FsfCHMkgI HTTP/1.1
Host: slc05ylp.us.oracle.com:14101
Accept-Encoding: gzip, deflate
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Cookie: JSESSIONID=dncVJT4HGCGtqjF30GklycQHvmyRs6vHp5PLhRTvL8HLwzgZP8cp!575725555
Accept-Language: en-us
Origin: https://accounts.google.com
Connection: keep-alive
User-Agent: Mozilla/5.0 (iPhone; CPU iPhone OS 7_1 like Mac OS X) AppleWebKit/537.51.2 (KHTML, like Gecko) Mobile/11D167

HTTP/1.1 302 Moved Temporarily
Connection: close
Date: Fri, 31 Oct 2014 11:54:54 GMT
Transfer-Encoding: chunked
Location: app://show.room.iphone?oicMobileAppRequestID=ShowRoomiPhone&payload=%7B%22UserProfile%22%3A%7B%22mail%22%3A%22andreluiz.correaneto%40gmail.com%22%2C%22lastname%22%3A%22Correa%22%2C%22firstname%22%3A%22Andre+Correa%22%7D%2C%22IdentityProvider%22%3A%22Google_OAuth2_Mobile%22%2C%22Protocol%22%3A%22OAuth%22%2C%22OICMobileAssertionToken%22%3A%22eyJhbGciOiJSUzUxMiIsInR5cCI6IkpXVCIsImtpZCI6Im9yYWtleSJ9.eyJleHAiOjE0MTQ3NjAwOTU2MDcsIm9yYWNsZS5vaWMudG9rZW4ucnAuaWRwX3VyaSI6Ikdvb2dsZV9PQXV0aDJfTW9iaWxlIiwib3JhY2xlLm9pYy50b2tlbi5ycC51c2VyX2lkX3VyaSI6Im1haWw6YW5kcmVsdWl6LmNvcnJlYW5ldG9AZ21haWwuY29tIiwiYXVkIjoib2FtX3NlcnZlcjEiLCJpc3MiOiJJbnRlcm5ldElkZW50aXR5QXV0aGVudGljYXRpb24iLCJwcm4iOiJtYWlsOmFuZHJlbHVpei5jb3JyZWFuZXRvQGdtYWlsLmNvbSIsImp0aSI6IjU1NTgxMDQ1LTc2ZTAtNDcwZS04N2VkLTMzY2EyMzQxZjFjOSIsIm9yYWNsZS5vaWMudG9rZW4udHlwZSI6IlVTRVJUT0tFTiIsImlhdCI6MTQxNDc1NjQ5NTYwNywib3JhY2xlLm9pYy50b2tlbi51c2VyX2RuIjoibWFpbDphbmRyZWx1aXouY29ycmVhbmV0b0BnbWFpbC5jb20gR29vZ2xlX09BdXRoMl9Nb2JpbGUifQ.g-MY_GI5TO1EirItAJ1TAiQIu31NI_rzwlLieJMnYXUA6uMBbMn1s5cz-PBKytO56uriUP7DRITA2YgFFnvaGJsUpKllR4Of0gX-z-Xxr_EsdTyGtsgfhQqU8bD61eyaEoWOyMtfEt1-XvcRTyX9FPq5DGi8gzCgyG460Zv6_BU%22%2C%22oauth_access_token%22%3A%22%7B%5C%22access_token%5C%22%3A%5C%22ya29.rwCyg8dspjdMXhiqCMn_BRDboAGh_h52erDf9M6gbZI7NupiHnAgo4a5PTmkz9JW_oYrR1SOdE8Q0A%5C%22%2C%5C%22expiry%5C%22%3A3600%2C%5C%22consumer%5C%22%3A%5C%22ShowRoomiPhone%5C%22%2C%5C%22provider%5C%22%3A%5C%22Google_OAuth2_Mobile%5C%22%7D%22%7D
Content-Type: text/html;charset=UTF-8
X-ORACLE-DMS-ECID: 6af0f0aa917fd32e:4ef3b382:1495d09e8d8:-8000-000000000000e62d
X-Powered-By: Servlet/2.5 JSP/2.1

 

5. Import IDMMobileSDK.h into the classes where you expect to perform authentication with the SDK APIs.

6. Code the authentication process

6.1. In your application delegate class, implement method application:openURL:sourceApplication:annotation. This is the method invoked when your iOS application receives a callback from M&S via its URL type. In the method, you MUST post a notification to IDM Mobile SDK, which reacts depending on the type of message it receives, invoking the various methods in the OMMobileServiceDelegate protocol.

// Called when application in invoked via some URL
- (BOOL)application:(UIApplication *)application
            openURL:(NSURL *)url
  sourceApplication:(NSString *)sourceApplication
         annotation:(id)annotation
{
    
    NSLog(@"handling callback after authentication...");
    NSMutableDictionary *userInfo = [[NSMutableDictionary alloc]
                                     initWithCapacity:1];
    
    [userInfo setObject:url forKey:OM_RESPONSE_URL];
    
    //Post the notification to IDM Mobile SDK
    [[NSNotificationCenter defaultCenter]
     postNotificationName:OM_PROCESS_URL_RESPONSE
     object:self
     userInfo:userInfo];
    
    return TRUE;
}

6.2. Initialize M&S properties. Since these properties are very static in nature, you could have them in your ViewController’s viewDidLoad method, as in:

- (void)viewDidLoad {
    [super viewDidLoad];

    NSMutableDictionary *sdkProps = [[NSMutableDictionary alloc] init];
    
    [sdkProps setObject:OM_PROP_AUTHSERVER_OAMMS forKey:OM_PROP_AUTHSERVER_TYPE];
    [sdkProps setObject:@"http://slc05ylp.us.oracle.com:14101" forKey:OM_PROP_OAMMS_URL];
    [sdkProps setObject:@"ShowRoomiPhone" forKey:OM_PROP_APPNAME];
    [sdkProps setObject:@"MobileServiceDomain" forKey:OM_PROP_OAMMS_SERVICE_DOMAIN];
    
    self.mss = [[OMMobileSecurityService alloc]
                                    initWithProperties:sdkProps
                                    delegate:self];
    
    [self.mss setup];
}

Notice:

1. The initialization property values:

a) Key OM_PROP_OAMMS_URL is the OAM M&S server URL:

b) Key OM_PROP_APPNAME is the Mobile Service Application Profile name;

c) Key OM_PROP_OAMMS_SERVICE_DOMAIN is the mobile service domain to which the Mobile Service Application Profile has been added.

2. in the call self.mss = [[OMMobileSecurityService alloc] initWithProperties:sdkProps delegate:self]
delegate:self means that your ViewController implements the OMMobileServiceDelegate protocol, i.e., the varios methods called by OMMobileSecurityService.

 

6.2. Implement didReceiveApplicationProfile:error method of OMMobileServiceDelegate protocol for starting the authentication process.

- (void)didReceiveApplicationProfile:(NSDictionary *)applicationProfile error:(NSError *)error {
    NSError *err = nil;
    
    if(error) {
        NSString *msg = @"Error in receiving application profile";
        UIAlertView *av = [[UIAlertView alloc]initWithTitle:nil
                                                    message:msg
                                                   delegate:nil
                                          cancelButtonTitle:@"OK"
                                          otherButtonTitles:nil];
        [av show];
        av = nil;
    }

    else {
        OMAuthenticationRequest *authReq = [[OMAuthenticationRequest alloc] init];
    
        NSLog(@"Starting Authentication Process...");
    
        err = [self.mss startAuthenticationProcess:authReq presenterViewController:self];
    }
    
}

didReceiveApplicationProfile method is automatically invoked by OMMobileSecurityService once the application receives the Application Profile data from M&S. The method call starting the authentication process is

[self.mss startAuthenticationProcess:authReq presenterViewController:self];

 

6.3. Implement didFinishAuthentication:error method of OMMobileServiceDelegate protocol for receiving the callback from OMMobileSecurityService after authentication. If authentication succeeds, you should have access to token returned by M&S and by the IdP (if configured in M&S Social Identity Application Profile, per oic.app.idp.oauth.token application profile parameter).

-

- (void)didFinishAuthentication: (OMAuthenticationContext *)context
                          error: (NSError *)error {
    NSLog(@"didFinishAuthentication\nUser : %@\n Token : %@\n Error : %@",
          context.userName,context.tokenValue,error.localizedDescription);
    if(error) {
        NSString *msg = @"Error in authenticating user";
        UIAlertView *av = [[UIAlertView alloc]initWithTitle:nil
                                                    message:msg
                                                   delegate:nil
                                          cancelButtonTitle:@"OK"
                                          otherButtonTitles:nil];
        [av show];
        av = nil;
    }
    else {
        NSLog(@"Authentication success!");
        
        context = [self.mss authenticationContext:false];
        NSDictionary *tokens = [context accessTokens];
        NSLog(@"%d",tokens.count);
        
        for (id key in tokens) {
            NSLog(@"%@: %@", key, [tokens objectForKey:key]);
            
        }
    }
}

Notice:

1. context.tokenValue returns the JWT returned by M&S;
2. [tokens objectForKey:OM_ACCESS_TOKEN] returns the OAuth access token returned by Google;

 

Ending Remarks

In this post I’ve showed how to configure OAM M&S to provide authentication against Internet Identity providers on behalf of a native iOS application. Specifically, I’ve taken Google as the remote Internet Identity provider with the OpenID Connect protocol. As of OAM M&S 11.1.2.2., there’s no OOTB Internet Identity Provider for OpenID Connect (OAuth 2), so the article also covered how to create one.

The post also went into a considerable amount of detail on configuring Xcode and using M&S SDK in the iOS application.

The references I’ve consulted for this post are:

Managing Oracle Access Management Mobile and Social

Developing Mobile Services Applications with the iOS Client SDK

See you next time!


Integrating Oracle Access Management platform with Mobile Application Framework

$
0
0

Fellow A-Team blogger Andre Correa recently posted an article about integrating native IOS Apps with the OAM Mobile & Social SDK in order to do social identity federation within these apps.

To expand on that post – and present a potential alternative to developers who wish to use Oracle’s Mobile Application Framework – I’d like to draw attention to a post by UK-based Access Management guru Paul Toal. Paul is a Master Principal Sales Consultant and key member of the UK InfoSec team at Oracle. In his post, he describes how to integrate Oracle Access Management (including risk-based authentication and social login) into an application built using the cross-platform Oracle Mobile Application Framework.

You can read Paul’s post on his blog here.

Automated Policy Synchronization (APS) for OAM Cloned Environment

$
0
0

Introduction

Since the introduction of MDC support in OAM 11g, Customers have been asking for Automated Synchronization between Master and Clone OAM Environments. It is supported in OAM R2PS2. Thanks to the development team! Before R2PS2, It required T2P process to keep all the data centers in synch which is manual process or customer had to write crone jobs to run T2P process at frequent intervals. Please note that T2P process is still supported with R2PS2 if that is the preference for some reason.

How does APS function?

APS is client side pull model. Each client (clone environment) pulls changes from the server (Master environment). A Replication thread runs after every pre-configured time Interval on clone environment and fetches changes from replication service (REST Service) running on master environment.

For every cloned environment, Master environment keeps track of a change sequence number which indicates when cloned environment was last synched. Master environment also keeps track of change log which is list of changes (Create/Update/Delete) that have happened in the environment. Along with that, Master environment keeps track of mapping between cloned environment specific change sequence number and change log.

Cloned environment while updating configuration can transform configuration parameter values to environment specific values depending on transformation rules. This is very interesting and determines success/failure of APS in an environment. Unfortunately it is not well documented. No worries. I will talk about transformation rules in little more details in this blog.

 

Step-by-step process to configure APS

 

  1. 1. While setting up clone environment, make sure latest configuration is copied from master environment to clone environment. That is running copyConfig.sh to generate new oamt2pConfig.jar file  every time (As documented in MDC Implementation blog post by Vinay Kalra from A Team) you start setting up a new clone environment instead of using old oamt2pConfig.jar.
  2.  

  3. 2. For APS to work, partnerInfo.properties file used for MDC configuration (While running addPartnerForMultiDataCentre WLST command) should have an additional REST endpoint property defined as described below where NYC-CLUSTER (Master/Primary environment) and LON-CLUSTER (Clone environment) are two cluster IDs. You may already have run addPartnerForMultiDataCentre before; however you need to run that again with RESTEndpoint parameter if that was not added in partnerInfo.properties file when you had last run that. You need to run addPartnerForMultiDataCentre commands as below on both Master and Clone environments.

[addPartnerForMultiDataCentre(propfile="ABSOLUTE_PATH_OF_PrimaryPartnerInfo.properties")
addPartnerForMultiDataCentre(propfile="ABSOLUTE_PATH_OF_SecondaryPartnerInfo.properties")]

 

PrimaryPartnerInfo.properties for NYC-CLUSTER (Master environment) SecondaryPartnerInfo.properties for LON-CLUSTER (Clone environment)
remoteDataCentreClusterId=NYC-CLUSTER
oamMdcAgentId=MDC-NYC
PrimaryHostPort=oam1-nyc.oracle.com:5575
SecondaryHostPort=oam2-nyc.oracle.com:5575
AccessClientPasswd=******
oamMdcSecurityMode=Open
agentVersion=11g
RESTEndpoint=http://oam1-nyc.oracle.com:7001
remoteDataCentreClusterId=LON-CLUSTER
oamMdcAgentId=MDC-LON
PrimaryHostPort=oam1-lon.oracle.com:5575
SecondaryHostPort=oam2-lon.oracle.com:5575
AccessClientPasswd=******
oamMdcSecurityMode=Open
agentVersion=11g
RESTEndpoint=http://oam1-lon.oracle.com:7001

 

    1. 3. Make sure Master data center and clone data centers are marked as Master and Clone data centers respectively by running following WLST commands.

    setMultiDataCenterType(DataCenterType=”Master”) on Master data center Admin server
    setMultiDataCenterType(DataCenterType=”Clone”) on Clone data center Admin server

    1. 4. Now you have to add “-Doracle.oam.EnableMDCReplication=true” Java Property in setDomainEnv.sh file on both master and clone environments as shown below to enable APS service. After adding that Java property, restart admin servers.

APSConfigParameter

  1. 5. After enabling APS service, execute following curl command to test if APS is enabled on both the data centers. If it is enabled, you will see {“ok”:”true”} JSON response.

[oracle@oam1-nyc bin]$ curl -u weblogic ‘http://oam1-nyc.oracle.com:7001/oam/services/rest/_replication/hello’
Enter host password for user ‘weblogic':
{“ok”:”true”}

[oracle@oam1-lon bin]$ curl -u weblogic ‘http://oam1-lon.oracle.com:7001/oam/services/rest/_replication/hello’
Enter host password for user ‘weblogic':
{“ok”:”true”}

 

  1. 6. Now you need to setup replication agreement between master and clone environment by running following curl command. Service responds back with JSON object that has identifier for the replication agreement. Save that identifier because you have to use that identifier to update or delete replication agreement.

Request: curl -u weblogic:****** -H ‘Content-Type: application/json’ -X POST ‘http://oam1-nyc.oracle.com:7001/oam/services/rest/_plication/setup’ -d  ‘{“name”:”NYCtoLON”, “source”:”NYC-CLUSTER”,”target”:”LON-CLUSTER”,”documentType”:”ENTITY”}’

Response: {“enabled”:”true”,“identifier”:”201409040157218184″,”ok”:”true”,“pollInterval”:”900″,“startingSequenceNumber”:”101″,”state”:”READY”}

I have highlighted some of the important parameters from JSON response.

First one is identifier. As mentioned above, it is a reference to replication agreement setup between NYC-CLUSTER and LON-CLUSTER data centers.

Second is polling Interval. Clone data center will poll for changes against master data center after every polling interval. Typically policy and configuration changes are not done very often and so this number can be as high as 900 seconds as setup by default by OAM. However you can change that if needed as we will do in next step.

Third one is startingSequenceNumber. That is the change sequence number that I talked about earlier in the blog post. Initial agreed upon sequence number is 101 in this example. Clone data center will start polling for changes that have happened after 101 sequence number. To understand more about sequence number and how it is used, refer to sequence diagram below.

7. Now using replication agreement identifier number, you can make changes in the replication agreement configuration. Before doing that, Run first command as below to get current status of replication agreement. As shown below, we are changing poll Interval to 60 seconds. Service responds back with JSON object that is the status of replication agreement before making the change. You need to fetch replication agreement status again to see updated configuration.

 Fetching Status of Replication Agreement
Request: curl -u weblogic:****** -H ‘Content-Type: application/json’  ‘http://oam1-nyc.oracle.com:7001/oam/services/rest/_replication/201409040157218184′
JSON Response: {“enabled”:”true”,”identifier”:”201409040157218184″,”ok”:”true”,”pollInterval”:”3600″,”startingSequenceNumber”:”101″,”state”:”ACTIVE”}
 Updating poll interval to 60 seconds
Request: curl -u weblogic:****** -H ‘Content-Type: application/json’  -X PUT ‘http://oam1-nyc.oracle.com:7001/oam/services/rest/_replication/201409040157218184′ -d ‘{“pollInterval”:”60″,”replicaType”:”consumer”}’
JSON Response: {“enabled”:”true”,”identifier”:”201409040157218184″,”ok”:”true”,”pollInterval”:”3600″,”startingSequenceNumber”:”101″,”state”:”ACTIVE”}
 Fetching Status if Replication Agreement again to validate change
Request: curl -u weblogic:****** -H ‘Content-Type: application/json’  ‘http://oam1-nyc.oracle.com:7001/oam/services/rest/_replication/201409040157218184′
JSON Response: {“enabled”:”true”,”identifier”:”201409040157218184″,”ok”:”true”,”pollInterval”:”60″,”startingSequenceNumber”:”101″,”state”:”ACTIVE”}
  1. 8. After setting up replication agreement, restart admin servers on both master and clone data centers.

Transformation Rules

By default APS uses following transformation rules that you can change if you need to.

Out-Of-The box transformation rules

<?xml version=”1.0″ encoding=”UTF-8″?>
<mdc-transform-rule>
    <changes-to-include entity-path=”/DeployedComponent/Agent/WebGate/Instance”>
        <replace attribute-match=”/*/PrimaryServerList/*/host” value-match=”(.*)”>
            <replace-with n=”1″>${DeployedComponent/Server/NGAMServer/Profile/OAMServerProfile/OAMSERVER/serverhost}</replace-with>
        </replace>
        <replace attribute-match=”/*/logoutRedirectUrl” value-match=”(.*)://(.*):(.*)/oam/server/logout”>
            <replace-with n=”1″>${DeployedComponent/Server/NGAMServer/Profile/OAMServerProfile/OAMSERVER/serverprotocol}</replace-with>
            <replace-with n=”2″>${DeployedComponent/Server/NGAMServer/Profile/OAMServerProfile/OAMSERVER/serverhost}</replace-with>
            <replace-with n=”3″>${DeployedComponent/Server/NGAMServer/Profile/OAMServerProfile/OAMSERVER/serverport}</replace-with>
        </replace>
    </changes-to-include>
    <changes-to-include entity-path=”/DeployedComponent/Server/NGAMServer/Profile/AuthenticationModules”/>
    <changes-to-include entity-path=”/DeployedComponent/Server/NGAMServer/Profile/oamproxy”/>
    <changes-to-include entity-path=”/DeployedComponent/Server/NGAMServer/Profile/Sme/SessionConfigurations”/>
</mdc-transform-rule>

 

Above transformation rules make couple of changes in WebGate definitions. Let’s talk about each one of them.

WebGate ServerList transformation

<replace attribute-match=”/*/PrimaryServerList/*/host” value-match=”(.*)”>
    <replace-with n=”1″>${DeployedComponent/Server/NGAMServer/Profile/OAMServerProfile/OAMSERVER/serverhost}
    </replace-with>
</replace>

It updates PrimaryServerList for all the WebGates and replaces them with OAM server host from Clone environment. The best way to understand transformation rule is to open oam-config.xml file in web browser and browse through the tree. Above mentioned transformation rule replaces PrimaryServerList
with ${DeployedComponent/Server/NGAMServer/Profile/OAMServerProfile/OAMSERVER/serverhost} value. If I browse that value in oam-config.xml, I get oam1-lon.oracle.com value as shown in the screen below so APS thread will update PrimaryServerList host for every webgate agent to oam1-lon.oracle.com.

 

OAMServerConfiguration

 

The drawback or limitation of this transformation rule is; it updates all the servers/hosts in the PrimaryList with oam1-blv.oracle.com. You can update transformation rule as below so that it updates servers in PrimaryServerList with respective servers from Cloned data center.

We are updating 0th PrimaryServerList (oam1-nyc.oracle.com) with oam_server1 host (oam1-lon.oracle.com) from clone environment and 1st PrimaryServerList (oam2-nyc.oracle.com) with oam_server2 host (oam2-lon.oracle.com) from clone environment as shown and highlighted in the screen below.

Note: This transformation rule assumes that you have two OAM server instances in both Primary and Cloned environment. Similar to this transformation rule, you can choose to update SecondaryServerList as well for all the WebGates.

<changes-to-include entity-path=”/DeployedComponent/Agent/WebGate/Instance”>
    <replace attribute-match=”/*/PrimaryServerList/0/host” value-match=”(.*)”>
        <replace-with n=”1″>${DeployedComponent/Server/NGAMServer/Instance/oam_server1/host}
        </replace-with>
    </replace>
    <replace attribute-match=”/*/PrimaryServerList/1/host” value-match=”(.*)”>
        <replace-with n=”1″>${DeployedComponent/Server/NGAMServer/Instance/oam_server2/host}
        </replace-with>
    </replace>
</changes-to-include>

 

UpdatedTransformRule
It is recommended to use Load Balancer (LB) between WebGate and OAM server. If you are using it right, you do not have to update PrimaryServerList across data centers and so can remove this transformation rule from the XML. However you do need to update PrimaryServerList for IAMSuiteAgent and accessgate-oic unless you have configured those agents as well to talk to LB. Below change will make sure that PrimaryServerList is updated only for IAMSuiteAgent and accessgate-oic and not updated for any other webgate agent.

<changes-to-include entity-path=”/DeployedComponent/Agent/WebGate/Instance”>
    <replace attribute-match=”/IAMSuiteAgent/PrimaryServerList/*/host” value-match=”(.*)”>
        <replace-with n=”1″>${DeployedComponent/Server/NGAMServer/Profile/OAMServerProfile/OAMSERVER/serverhost}
        </replace-with>
    </replace>
    <replace attribute-match=”/accessgate-oic/PrimaryServerList/*/host” value-match=”(.*)”>
        <replace-with n=”1″>${DeployedComponent/Server/NGAMServer/Profile/OAMServerProfile/OAMSERVER/serverhost}
        </replace-with>
    </replace>
</changes-to-include>

WebGate logout URL transformation rule

Second change in the OOB transformation rule is logout URL. For all the WebGate agents, as shown below, it updates logout URL protocol, host and port with respective values from clone environment.

<replace attribute-match=”/*/logoutRedirectUrl” value-match=”(.*)://(.*):(.*)/oam/server/logout”>
    <replace-with n=”1″>${DeployedComponent/Server/NGAMServer/Profile/OAMServerProfile/OAMSERVER/serverprotocol}
    </replace-with>
    <replace-with n=”2″>${DeployedComponent/Server/NGAMServer/Profile/OAMServerProfile/OAMSERVER/serverhost}
    </replace-with>
    <replace-with n=”3″>${DeployedComponent/Server/NGAMServer/Profile/OAMServerProfile/OAMSERVER/serverport}
    </replace-with>
</replace>

If you used global LB to define logout URL for all the WebGate agents in master environment, then you don’t need to replace logoutURL in clone environment and can remove this transformation rule.

If you are using DCC authentication scheme and using global LB hostname to define DCC login and logout URL, then also you don’t need to replace login and logout URL in cloned environment and can remove the transformation rule.

Now that you understand how to write custom transformation rules, it’s time to configure OAM to use custom transformation rules which unfortunately is not documented. You need to update setDomainEnv.xml file as shown in the below screen shot on clone environment. Each clone environment can use different transformation rules. Restart admin server in clone environment after changing transformation rule.

APSTransformConifParameter

APS as I said in the beginning was a long pending feature and I hope this blog will help you setup MDC environment with APS. If you create environment specific transformation rules, please share it here so that everyone will benefit from it.

Configuring OAM SSO for ATG BCC and Endeca XM

$
0
0

Introduction

Single sign-on, or “SSO” as it’s commonly referred to, is an authentication method that allows a user access to multiple applications through a single, secure, point of entry. Rather than authenticate separately for each application, users authenticate once through a centralized service. The benefits of SSO to end users are obvious, but there are also many cost and compliance advantages that are of interest to large organizations, which is why Oracle’s enterprise customers have increasingly demanded SSO integration with Oracle Access Manager (OAM). With the introduction Oracle Commerce 11 they now have it, and in this blog I will be demonstrating how to use OAM to enable SSO between the ATG Business Control Center (BCC) and Endeca Experience Manager (XM).

Main Article

E-commerce applications are rarely simple. Often they require access to a variety of disparate systems, including inventory, fulfillment, service center, and marketing systems. A common obstacle when working with such heterogeneous systems is authenticating and preserving identity integrity. In response, many organizations choose to incorporate single sign-on solutions into their integration architecture. To meet customer demands, as well as continue its vision of unifying the Commerce toolset, Oracle has introduced in its Commerce 11.0 release a Commerce-only SSO solution that comes standard, and an Enterprise SSO solution that leverages Oracle Access Manager. The focus of this article is on the latter, illustrating how OAM can be used to provide single sign-on capability between the ATG BCC and Endeca Workbench/XM, as well as other Oracle and non-Oracle products.

Oracle Access Manager (OAM) is an industry-leading Web Access Management (WAM) solution that provides Web Single Sign-On, centralized policy administration, real-time session management and auditing. It is core to Oracle’s Access Management platform. OAM enforces access policies using web server agents called as WebGates. The WebGates intercept site traffic and verify that the user is authenticated and authorized to access the requested resource. If the user isn’t yet authenticated, the WebGate redirects the user to a login page, which validates the user’s credentials against a user repository. Once authenticated, a session gets established on the Access Manager server, and as the user tries to access different applications and resources, the Access Manager server evaluates whether the user is permitted to access that particular resource, and conveys its decision back to the WebGate for enforcement.

The procedure outlined below demonstrates how to install and configure OAM for use with Oracle Commerce 11 for authentication only. Authorizations are still managed by the respective product consoles. This article assumes that the reader is familiar with Oracle Commerce, but new to OAM. As such, I demonstrate the basic install procedure for OAM. This information is no substitute for product installation and configuration documentation, and may be incomplete. It is therefore recommended that the reader first review the product documentation and use this article only to augment or bolster their understanding.

Installing OAM 11gR2

To configure Oracle Commerce for SSO with Oracle Access Manager, an OAM environment must exist and be accessible to the Commerce servers. Below is a basic installation procedure for OAM on a Linux based environment, intended to help Commerce developers configure a local environment for testing and further exploration. If you have access to an existing OAM environment, then feel free to skip this section and continue to Commerce configuration, noting the host and port differences.

Installation Procedure

  1. Start by downloading the following software
    • • Oracle Identity and Access Management 11g (11.1.2.2.0)
    • • Oracle Fusion Middleware Repository Creation Utility 11g (11.1.2.2.0)
    • • Oracle Access Manager OHS 11g WebGates 11.1.2.2.0
    • • Oracle WebTier Utilities 11gR1 (11.1.1.7)
    • • Oracle WebLogic Server 10.3.6
    • • Java SE Development Kit 6u45
  2. Install the RCU schema
    Extract “ofm_rcu_linux_11.1.2.2.0_64_disk1_1of1.zip” and run rcu in a 32-bit shell:
    linux32 bash
    ./rcuHome/bin/rcu
    

    Database Type: Oracle Database
    Host Name: localhost
    Port: 1521
    Service Name: orcl
    Username: sys
    Password: password

    Select “Oracle Access Manager” under Identity Management
    Use the same password for all schemas: welcome1

  3. Install Java and WebLogic Server
    Extract “jdk-6u45-linux-x64.bin” to /app/oracle/product/fmw11g/jdk160_45. Then run:
    java -jar wls1036_generic.jar
    

    Install to: /app/oracle/product/fmw11g

    If the GUI doesn’t start, try:

    yum install libXtst.i686
    
  4. Install Oracle Access Manager
    Extract “ofm_iam_generic_11.1.2.2.0_disk1_1of2.zip” and “ofm_iam_generic_11.1.2.2.0_disk1_2of2.zip” and run the OAM installer:
    ./Disk1/runInstaller -jreLoc /app/oracle/product/fmw11g/jdk160_45
    

    Oracle Middleware Home: /app/oracle/product/fmw11g
    Oracle Home Directory: idm_11.1.2

    If the Prerequisite Checks fail during installation, try:

    yum install compat-libcap1
    yum install compat-libstdc++-33.i686
    

    Note: To remove OAM, you can run the installer again with the -deinstall option.

    cd /app/oracle/product/fmw11g
    ./idm_11.1.2/oui/bin/runInstaller -deinstall
    
  5. Create a WebLogic Domain for the OAM Servers
    . /app/oracle/product/fmw11g/wlserver_10.3/server/bin/setWLSEnv.sh
    /app/oracle/product/fmw11g/wlserver_10.3/common/bin/config.sh
    

    Select:
    • Oracle Access Management
    • Oracle Enterprise Manager

    Domain Name: idm_domain
    Password: welcome1

    Select both Schemas and change:

    DBMS/Service: orcl
    Host Name: localhost
    Password: welcome1

  6. Upgrade Schemas using Patch Assistant
    Run the Patch Assistant:
    /app/oracle/product/fmw11g/oracle_common/bin/psa
    

    Select:
    • Oracle Access Manager

    Connect String: localhost:1521/ORCL
    DBA User Name: sys as sysdba
    DBA Password: password

    Schema User Name: DEV_IAU
    Schema Password: welcome1

  7. Create a Security Store for the WLS Domain
    cd /app/oracle/product/fmw11g/idm_11.1.2/common
    bin/wlst.sh tools/configureSecurityStore.py -d /app/oracle/product/fmw11g/user_projects/domains/idm_domain -c IAM -p welcome1 -m create
    

    Note: if you encounter any issues, re-run configureSecurityStore.py using “-m validate_fix”, instead of “-m create”. Then run “-m validate” to verify the configuration.

  8. Start WebLogic Servers
    cd /app/oracle/product/fmw11g/user_projects/domains/idm_domain
    ./startWebLogic.sh
    ./bin/startManagedWebLogic.sh oam_server1
    

    The following URLs should now be accessible:
    http://localhost:7001/console
    http://localhost:7001/em
    http://localhost:7001/oamconsole

  9. Install Oracle WebTier Utilities 11gR1
    Extract “ofm_webtier_linux_11.1.1.7.0_64_disk1_1of1.zip” and execute ./Disk1/runInstaller
    Select “Install Software – Do Not Configure”

    Oracle Middleware Home: /app/oracle/product/fmw11g
    Oracle Home Directory: webtier_11.1

    /app/oracle/product/fmw11g/webtier_11.1/bin/config.sh
    

    Select:
    • Oracle HTTP Server
    • Associate Selected Components with WebLogic Domain

    Make sure the WLS Admin Server is running, and specify the OAM Admin port number (7001).

    Instance Home Location: /app/oracle/product/fmw11g/webtier_11.1/instances/instance1
    Instance Name: instance1
    OHS Component Name: ohs1

  10. Install OAM 11gR2 (11.1.2.2) Webgate for OHS 11gR1 (11.1.1.7)
    Extract “ofm_webgates_generic_11.1.2.2.0_disk1_1of1.zip” and run Installer:
    ./Disk1/runInstaller -jreLoc /app/oracle/product/fmw11g/jdk160_45
    

    Oracle Middleware Home: /app/oracle/product/fmw11g
    Oracle Home Directory: webgate_11.1.2

    cd /app/oracle/product/fmw11g/webgate_11.1.2/webgate/ohs/tools/deployWebGate
    ./deployWebGateInstance.sh -w /app/oracle/product/fmw11g/webtier_11.1/instances/instance1/config/OHS/ohs1 -oh /app/oracle/product/fmw11g/webgate_11.1.2
    
    export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/app/oracle/product/fmw11g/webtier_11.1/lib:/app/oracle/product/fmw11g/webgate_11.1.2/webgate/ohs/lib
    
    cd /app/oracle/product/fmw11g/webgate_11.1.2/webgate/ohs/tools/setup/InstallTools
    ./EditHttpConf -w /app/oracle/product/fmw11g/webtier_11.1/instances/instance1/config/OHS/ohs1 -oh /app/oracle/product/fmw11g/webgate_11.1.2 -o webgate.conf
    
  11. Start OHS
    cd /app/oracle/product/fmw11g/webtier_11.1/instances/instance1/bin
    ./opmnctl startall
    

    To verify that OHS started successfully, open a browser and access the following URL:
    http://localhost:7777

    If you don’t see a welcome page, then the server is not running. Check the OHS log in the diagnostics directory and ensure that there are no errors being reported. If you see the following error: “libexpat.so.0: cannot open shared object file” then you may need to install libexpat using the procedure below.

    Download the latest Oracle Linux 6 repo configuration file and install compat-expat1:

    su - root
    cd /etc/yum.repos.d
    wget http://public-yum.oracle.com/public-yum-ol6.repo
    yum install compat-expat1
    
  12. Uninstall Procedure (in case of emergency)
    In the event that something goes wrong and you need to remove and re-install the products, the following commands can be used to uninstall everything:
    cd /app/oracle/product/fmw11g
    ./webgate_11.1.2/oui/bin/runInstaller -deinstall
    ./webtier_11.1/oui/bin/runInstaller -deinstall
    ./idm_11.1.2/oui/bin/runInstaller -deinstall
    <RCU_INSTALLER>/rcuHome/bin/rcu   (select the Drop Schema option)
    

    Optional:

    ./oracle_common/oui/bin/runInstaller -jreLoc /app/oracle/product/fmw11g/jdk160_45 -deinstall
    rm -f /app/oracle/product/fmw11g
    

This should be sufficient for a simple OAM installation. For configurations beyond the scope of this basic install procedure, or for more detailed instructions, please refer to the product installation documentation for OAM, which can be found here:

Quick Installation Guide for Oracle Identity and Access Management
Installation Guide for Oracle Identity and Access Management

Configuring Oracle HTTP Server (OHS) Proxy

In order for OAM to intercept Commerce requests the traffic must be routed through an Oracle HTTP Server (OHS) where an OAM WebGate agent resides. In steps 9-11 above, we installed and configured an OHS server with a WebGate agent, but we need to amend this configuration to proxy requests from OHS to the ATG BCC and Endeca Workbench/XM. Assuming that your ATG environment will be running on Oracle WebLogic Server, the simplest way to achieve this is to use separate OHS Virtual Hosts for the BCC and XM, and to proxy from the root path using the WebLogic Proxy Plug-in.

In my setup, I chose to install everything into virtualized environments using Oracle VirtualBox. This isn’t necessary, but can be useful if you’re working with multiple versions of these products. I installed the Commerce software in a separate Virtual Machine (VM) than the Security software to avoid possible port conflicts, and increase the reusability of my VMs, but this isn’t necessary either. If you wanted to install everything in one environment, that would work as well, provided you have the hardware to support it. My VMs communicate with one another by leveraging a feature new to VirtualBox 4.3+ known as “NAT Networking” which allows virtual machines to talk to each other on the same host and communicate with the outside world.

In my configurations below, you’ll see references to the hostnames “hadrian” and “tiberius”. These are the hostnames of my VMs, which are named respectively after the Roman emperors, who built the defensive fortification known as Hadrian’s Wall to keep the barbarians out, and who replenished the imperial treasury. Feel free to use any hostname that makes it easy to remember which server is which.

To configure the virtual hosts and set up the proxy rules, edit the file mod_wl_ohs.conf:

cd /app/oracle/product/fmw11g/webtier_11.1/instances/instance1/config/OHS/ohs1
vi mod_wl_ohs.conf

And add a section similar to the following, noting that your hostnames and port numbers may differ:

LoadModule weblogic_module   "${ORACLE_HOME}/ohs/modules/mod_wl_ohs.so"

<IfModule weblogic_module>
  Debug ON
  WLLogFile /tmp/weblogic.log

  Listen 7778
  <VirtualHost *:7778>
    <Location />
        SetHandler weblogic-handler
        WebLogicHost tiberius
        WebLogicPort 8006
    </Location>
  </VirtualHost>

  Listen 7779
  <VirtualHost *:7779>
    <Location />
        SetHandler weblogic-handler
        WebLogicHost tiberius
        WebLogicPort 7103
    </Location>
  </VirtualHost>

</IfModule>

This will proxy all requests made to hadrian on port 7778 to the Endeca server running Workbench/XM on tiberius:8006, and all requests made on port 7779 to the ATG server running on tiberius:7103. It is possible to proxy from a single host, but you would need to define location handlers for all the various proxy paths (/atg, /ifcr, /preview, /rest, /js, /dojo-1, …) because ATG does not keep all of its URL paths under an “/atg” context.

For these changes to take effect, you will need to stop and restart OHS:

cd /app/oracle/product/fmw11g/webtier_11.1/instances/instance1/bin
opmnctl stopall
opmnctl startall

Afterwards, the new URL for accessing the Endeca Workbench/XM through OHS/OAM will be:
http://hadrian:7778/ifcr

And the new URL for accessing the ATG BCC through OHS/OAM will be:
http://hadrian:7779/atg/bcc

For more information on configuring Virtual Hosts or the WebLogic Proxy Plug-in, you can also consult the following resources:

Apache Virtual Host Documentation
Using Web Server Plug-Ins with Oracle WebLogic Server

Enabling OAM for ATG Commerce BCC

Next we need to configure ATG Commerce to accept OAM authenticated users. The easiest way to configure OAM on ATG Commerce is to use the ATG Configuration and Installation Manager (CIM). CIM is a text-based application that simplifies configuration for ATG products. You can launch it by executing cim.sh from the “$ATG_INSTALL/ATG/home/bin” directory. At the end of the Product Selection phase of CIM configuration, you have the option to enable product add-ons. One of the product add-on options is “Single Sign On (SSO)”. To enable OAM-based SSO with ATG Commerce, you must enable the SSO add-on, and then select “OAM Authentication” as the SSO authentication model. Below is a sample transcript of such a session.

[oracle@localhost]$ /app/oracle/product/atg/ATG/home/bin/cim.sh

The following installed ATG components are being used to launch:
  ATGPlatform version 11.0 installed at /app/oracle/product/atg/ATG

Nucleus running

     Oracle ATG Web Commerce Configuration Installation Manager

-------START OPSS SERVICES------------------------------------------------------
enter [h]Help, [q]Quit to exit 

Starting the Oracle Platform Security Services (OPSS)

=======CIM MAIN MENU============================================================
enter [h]Help, [q]Quit to exit 

Choose the task you want to perform:
  [1]  Database Configuration - Done
  [2]  Configure OPSS Security - Done
  [3]  Server Instance Configuration - Done
  [4]  Application Assembly & Deployment - Done
  [R]  Set the Administrator Password - Done
  [P]  Product Selection - Done (ATG REST & ATG Site Administration & 
ATG-Endeca Integration & Oracle ATG Commerce Service Center & Oracle Commerce 
Reference Store & ATG Content Administration)
  [A]  Select Application Server - Done (Tomcat)
 *[C]  Custom CIM Plugin Launcher 

 > P

-------ANALYZING PRODUCT DIRECTORIES--------------------------------------------

Please wait as CIM analyzes your product folders. . . . . . . . . . . . 
Analysis complete: 6 seconds

-------WARNING------------------------------------------------------------------
enter [h]Help, [m]Main Menu, [q]Quit to exit 

Changing your product selection may require changes to your configuration. 
Database Configuration, Server Instance Configuration, and Application 
Assembly and Deployment will need to be redone. Are you sure you want to 
continue?
 
 *[C]  Continue
  [A]  Cancel

 > C

-------PRODUCT SELECTION--------------------------------------------------------
enter [h]Help, [m]Main Menu, [q]Quit to exit 

Select product you wish to configure by entering the corresponding item number.

  (Searching for products... done.)

  Choose one of the following options: (* = Currently selected )

  [1]  ATG Platform - 
        Includes, optionally, data warehouse components
 
 *[2]  ATG REST - 
        RESTful Web Services
 
  [3]  WebCenter Sites Extensions - 
        Includes ATG Platform and Endeca Reader.
 
 *[4]  ATG Site Administration - 
        Includes ATG Platform and Content Administration
 
 *[5]  ATG-Endeca Integration - 
        Includes ATG Platform. Select this option when Endeca is used.
 
 *[6]  ATG Content Administration - 
        Includes ATG Platform.  Optional: Preview
 
  [7]  ATG Commerce - 
        Includes ATG Platform and Content Administration. Optional: data 
        warehouse components, Preview and Merchandising UI
 
  [8]  Endeca Reader - 
        Includes ATG Platform. Select this option when Endeca is used to 
        import data to ATG.
 
 *[9]  Oracle ATG Commerce Service Center - 
        Agent-facing commerce application
 
 *[10]  Oracle Commerce Reference Store - 
        Includes the ATG platform, ATG-Endeca Integration, ATG Content 
        Administration, Site Administration, Oracle ATG Web Commerce, and 
        Oracle ATG Web Commerce Merchandising. Optional: data warehouse 
        components and Preview
 
  [D]  Done

Select one or more > D

-------ENDECA SEARCH------------------------------------------------------------
enter [h]Help, [m]Main Menu, [q]Quit to exit 

The following addon(s) have been automatically included for the selected 
product: Endeca Search

-------MERCHANDISING UI---------------------------------------------------------
enter [h]Help, [m]Main Menu, [q]Quit to exit 

The following addon(s) have been automatically included for the selected 
product: Merchandising UI

-------CHOOSE ADDONS :----------------------------------------------------------
enter [h]Help, [m]Main Menu, [q]Quit to exit 

  Choose AddOns :
  [1]  Reporting
  [2]  Staging Server
  [3]  Dedicated Lock Servers
 *[4]  Single Sign On (SSO)
  [5]  Abandoned Order Services
 *[6]  Preview Server
  [D]  Done

Select zero or more > D

-------SSO AUTHENTICATION-------------------------------------------------------
enter [h]Help, [m]Main Menu, [q]Quit to exit 

  SSO Authentication
 *[1]  Commerce Only SSO Authentication
  [2]  OAM Authentication

Select one > 2

-------INCLUDE DEMO APPLICATION:------------------------------------------------
enter [h]Help, [m]Main Menu, [q]Quit to exit 

  Include Demo Application:
  [1]  Quincy Funds Demo
  [D]  Done

Select zero or one > D

Once the SSO add-on has been enabled, and OAM Authentication selected as the authentication method, you can configure your production and publishing servers, like you would in a typical ATG Commerce installation, but use the OHS server values instead. So, where you see:

  • Fully-qualified Workbench Hostname – use the complete hostname of the OHS server.
  • Workbench Port Number – use the OHS virtual host port that proxies to Endeca Workbench.
  • OAM Web Server Hostname – use the hostname of the OHS server instead.
  • OAM Web Server Port – use the OHS virtual host port that proxies to ATG BCC.

For example, here are the values that I used throughout my configuration:

Fully-qualified Workbench Hostname  : hadrian.us.oracle.com
Workbench Port Number               : 7778
OAM Remote User Http Header Name    : OAM_REMOTE_USER
OAM Web Server Hostname             : hadrian
OAM Web Server Port                 : 7779
Webgate Logout URL                  : /oamsso/logout.html?end_url=/atg/bcc?dummy=1

After completing the CIM configuration, the following files should have been added or modified:

/app/oracle/product/atg/ATG/home/servers/atg_pub/localconfig
     /atg/dynamo/servlet/dafpipeline
          OamRemoteUserServlet.properties
          DynamoHandler.properties
          AccessControlServlet.properties
     /atg/dynamo/servlet/pipeline
          RedirectURLValidator.properties
     /atg/endeca
          ApplicationConfiguration.properties
     /atg/remote/controlcenter/service
          ControlCenterService.properties
     /atg/userprofiling
          InternalProfileFormHandler.properties
     /atg/userprofiling/oam
          Configuration.properties
          NonTransientLogoutAccessController.properties
     /atg/web/assetmanager/userprofiling
          NonTransientAccessController.properties
/app/oracle/product/atg/ATG/home/servers/atg_prod/localconfig
     /atg/endeca
          ApplicationConfiguration.properties

If your environment is already configured and you don’t want to use CIM, it’s probably best to run CIM in a different environment to get the modified files, then run diff checks against the above files to determine what changes need to be applied, and manually apply them.

Once the above procedure is complete, we’ll have all we need to accept OAM authenticated users from the ATG BCC, but we still need to create an OAM policy to secure the application and redirect to the OAM SSO Login Page when unauthenticated requests to port 7779 are made. We’ll get into that after first discussing the additional changes necessary for Endeca OAM integration.

For additional information on the ATG OAM integration, you can also refer to the following:

Using Oracle Access Management for Single Sign On
Installing the Oracle Access Manager Integration Component

Enabling OAM for Endeca Workbench/XM

Like ATG, Endeca also needs to be configured accept OAM authenticated users, but unlike ATG, there is no CIM configuration wizard for Endeca. The changes must be made through manual edits on Endeca configuration files. Outlined below is the procedure that I followed to configure Endeca for OAM SSO.

  1. Edit the webstudio.properties file:
    cd /app/oracle/product/endeca/ToolsAndFrameworks/11.0.0/server/workspace/conf
    vi webstudio.properties
    

    And apply the following changes:

    a) Set useOAM to true, and set logoutURL as follows:

    # OAM Authentication
    com.endeca.webstudio.useOAM=true
    #com.endeca.webstudio.oam.identityAssertionValidation=true
    #com.endeca.webstudio.oam.keyStore=oamkeystore.ks
    #com.endeca.webstudio.oam.keyStoreType=JKS
    #com.endeca.webstudio.oam.keyStorePassword=oampass
    com.endeca.webstudio.oam.logoutURL=/ifcr/system/sling/logout.html?oam.logout.url=/oamsso/logout.html%3Fend_url=/ifcr
    

    b) Set useSSO to false, and comment out the Commerce SSO section:

    # Commerce SSO Authentication
    com.endeca.webstudio.useSSO=false
    #com.endeca.webstudio.sso.loginURL=http://localhost:38840/sso/login
    #com.endeca.webstudio.sso.controlURL=http://localhost:38840/sso/control
    #com.endeca.webstudio.sso.logoutURL=http://localhost:38840/sso/logout
    #com.endeca.webstudio.sso.validationURL=http://localhost:38840/sso/validate
    #com.endeca.webstudio.sso.keepAliveURL=http://localhost:38840/sso/keepAlive
    #com.endeca.webstudio.sso.keepAliveFrequency=1800
    
  2. In the same directory, edit the ws-extensions.xml file, and change the url attributes to point to the OHS virtual host for the ATG BCC:
    <extension id="bcc-home" defaultName="BCC" defaultDescription ="BCC"
      url="http://hadrian:7779/atg/bcc"
        externalURL="true"/>
        <extension id="bcc-access-control"
          defaultName="BCC Access Control"
          defaultDescription="BCC Access Control"
          role="admin"
          url="http://hadrian:7779/ControlCenter/application/accesscontrol"
          externalURL="true"/>
    </extensions>
    
  3. Edit the file Login.conf, and uncomment the Webstudio section. Then modify the serverInfo, serviceUsername, and servicePassword properties to point to the same LDAP repository that OAM checks against. In my configuration, that was the WebLogic Server Embedded LDAP. An example of my file is shown below:
    Webstudio {
        com.endeca.workbench.authentication.ldap.WorkbenchLdapLoginModule required
        serverInfo="ldap://hadrian:7001"
        serviceUsername="cn=Admin"
        servicePassword="welcome1"
        serviceAuthentication="simple"
        authentication="simple"
        useSSL="false" keyStoreLocation="/app/oracle/product/endeca/ToolsAndFrameworks/11.0.0/server/workspace/conf/webstudio.jks"
        keyStorePassphrase="keypass"
    
        // The query used to look up a user in the LDAP directory and
        // templates that extract information from the user object
        userPath="/ou=people,ou=myrealm,dc=idm_domain??sub?(&(objectClass=person)(uid=%{#username}))"
        userTemplate="%{#uid}"
        firstNameTemplate="%{#givenName}"
        lastNameTemplate="%{#sn}"
        emailTemplate="%{#mail}"
    
        // The query used to look up a group in the LDAP directory and
        // templates that extract information from the group object
        findGroupPath="/ou=groups,ou=myrealm,dc=idm_domain??sub?(&(objectClass=group)(cn=%{#groupname}))"
        findGroupTemplate="%{#dn:0}"
        groupEmailTemplate="%{#mail}"
    
        // The query and template used to fetch the groups associated
        // with a user when the user logs in to Web Studio
        groupPath="/ou=groups,ou=myrealm,dc=idm_domain??sub?(member=%{#dn})"
        groupTemplate="%{#dn:0}"
    ;
    };
    
  4. The servicePassword specified in step 3 above is not the password for the weblogic or admin user, but rather the password for the WebLogic Embedded LDAP admin user (“cn=Admin“). The password you specify in the servicePassword field must match with the Embedded LDAP password configured in WebLogic Server.
    To set this password, log into the WebLogic Admin Console for the OAM environment (http://hadrian:7001/console) and navigate to “idm_domain ▶ Security ▶ Embedded LDAP”, and change the value of the credential field to use the same password. Then save and apply your changes.
    commerce+oam_wls_sec_realm
  5. While you’re in the WebLogic Admin Console, add a user named “admin”. Navigate to “Security Realms ▶ myrealm ▶ Users and Groups ▶ Users”, and click the “New” button to add a new user named admin. Don’t worry about assigning groups to this user because authorization will be done in the BCC and in Workbench.
    commerce+oam_wls_admin_user
  6. Log into the Endeca Workbench. Navigate to User Management, click on the admin user and change the Source from Workbench to LDAP:
    commerce+oam_wb_admin_user

New users created must be synchronized between WebLogic Server, Workbench, and the ATG Profile Repository. That is, if you create a new user in the WebLogic security realm, and you want that user to be able to log into Workbench, as well as log into the ATG BCC, then you must also create that user in Workbench, as well as in the ATG Profile Repository.

The procedure outlined here is sufficient if Workbench and OAM are both behind the same firewall, but if that’s not the case, you may want to enable trust between the two systems by enabling Identity Assertion Validation.

More information on IA validation and configuring Endeca with OAM can be found in:

Oracle Endeca Commerce Administrator’s Guide

Configuring OAM Security Policies for BCC and Workbench/XM

The final steps of this process are to configure the security policies that protect the BCC and Workbench/XM. These applications already have their own individual login pages, but this procedure will allow them to use a single, shared, login page, that bypasses the application specific logins and only requires users to sign in once to access both applications.

All security policy configuration is done using the Oracle Access Management Console, so start by opening a browser and logging into the OAM console (http://hadrian:7001/oamconsole).

  1. Register a WebGate agent:
    a) From the Launchpad, under Quick Start Wizards, select “SSO Agent Registration”.
    b) As the type, select “11g Webgate” and click Next.
    c) Enter “OHS1_WebGate” as the name, and “hadrian.us.oracle.com” as the preferred host.
    commerce+oam_oamconsole_wgagent

    d) Click Finish.

  2. Create Host Identifiers for the ATG and Endeca servers:
    a) From the Launchpad, under Access Manager, select “Host Identifiers”.
    b) Click the “Create Host Identifier” button.
    c) Use name “endeca_wb1″, and “hadrian.us.oracle.com:7778″ for host and port, then click Apply.
    commerce+oam_oamconsole_hostid

    d) Repeat for ATG server, using:

    Name: atg_pub1
    Description: Host identifier for ATG Publishing
    Host Name: hadrian.us.oracle.com
    Port: 7779
  3. Create an Application Domain:
    a) From the Launchpad, under Access Manager, select “Application Domains”.
    b) Click the “Create Application Domain” button. Enter the following, and click Apply.
    Name: ATG/Endeca
    Description: Policy objects enabling integration with ATG and Endeca.
  4. Create an Authentication Policy:
    a) On the newly created application domain, select the “Authentication Policies” tab.
    b) Click the “Create Authentication Policy” button.
    c) Name the policy “Endeca” and select “LDAPScheme” for authentication. Then click Apply.
    commerce+oam_oamconsole_atnpolicy

    d) Click the “Duplicate” button to create another similar policy, this time using the following:

    Name: ATG
    Description: ATG SSO using LDAP authentication.
  5. Create an Authorization Policy:
    a) Return to the ATG/Endeca application domain, and select the “Authorization Policies” tab.
    b) Click the “Create Authorization Policy” button, and name the policy “open”.
    c) Select the “Conditions” tab, and add a condition of type True (name will auto-populate).
    d) Select the “Rules” tab, and in the “Allow Rule” section, move the TRUE condition from Available to Selected, and click Apply.
    commerce+oam_oamconsole_rules
  6. Define the Resource URLs to protect:
    a) Return to the ATG/Endeca application domain, and select the “Resources” tab.
    b) Click the “New Resource” button, and create a new resource of type HTTP with:
    Host Identifier: endeca_wb1
    Resource URL: /**
    Protection Level: Protected
    Authentication Policy: Endeca
    Authorization Policy: open
    commerce+oam_oamconsole_resources

    c) Click the “Duplicate” button to create another similar resource, this time using the following:

    Host Identifier: atg_pub1
    Resource URL: /**
    Protection Level: Protected
    Authentication Policy: ATG
    Authorization Policy: open
  7. Conclusion

    Once you’ve completed the procedures above, and have restarted all of your servers, your environment will be SSO enabled using Oracle Access Manager. Your users should use the frontend host addresses to log into the BCC and XM and will be able to toggle between the two consoles without having to re-authenticate.

    To verify your configuration, try logging into either of the following two URLs (hostname may differ):
    http://hadrian:7778/ifcr
    http://hadrian:7779/atg/bcc

    If everything is configured correctly, you will be presented with the Oracle Access Manager Login page:

    commerce+oam_oam_loginpage

    Log in using the password specified when creating the admin user in the WebLogic Admin Console (welcome1), and you should proceed to either the BCC or XM management console.

    From the BCC, under “Oracle Commerce Tools” section, you should see a link for the Endeca Workbench:

    commerce+oam_bcchome

    Clicking on the link will navigate to the Endeca Workbench without requiring you to authenticate again. From the Endeca Workbench/XM, you should also see a link that can take you back to the ATG BCC:

    commerce+oam_xmhome

    Hopefully this article provides the necessary insight to administrators, architects, and developers, who are looking to integrate OAM into their Commerce solutions. Please keep in mind that the procedures outlined herein are intended for development environments, and that additional steps may be required for production environments. Please make sure to also review the product literature when configuring your environments.

Using OAAM Risk Evaluation in OAM Authorization Policies

Next: OAAM_SAMPLE with different integration and/or deployment options
Previous: Configuring OAM SSO for ATG BCC and Endeca XM
$
0
0

We recently encountered an interesting requirement about taking decision within OAM Authorization policy based on the Risk-evaluation performed by OAAM during Authentication flow. Considering the interesting nature of the requirement / use-case, I thought to share details about the implementation approach through this blog post.

Before I go into details about the implementation approach, let me explain the requirement / use-case as example with a few bullet points:

  • Requirement was to allow users from only selected country/state to access selected resources after authentication.
  • User should be authenticated only once.
  • Only certain applications / resources should be restricted based on the geo-location identified by IP Address.

Using above mentioned use case, idea here for this blog post is to provide details about how risk-evaluation performed by OAAM during Authentication flow can useful while taking decision as part of Authorization policy in OAM. The approach would be useful for other use-cases as well of similar nature.

The implementation approach (using feature known as IdentityContext) we are going to discuss further is considering the assumptions mentioned below:

  • IAM Suite version 11.1.2.2.0 or later
  • Advanced integration between OAM and OAAM using TAP (TapTokenVersion v2.1)

Identity Context (shared between OAM and OAAM) allows context-aware policy management and authorization capabilities built into the Oracle Access Management platform. The Identity Context feature is helpful in securing access to resources using traditional security controls (such as roles and groups) as well as dynamic data established during authentication and authorization (such as authentication strength, risk levels, device trust and the like).

The solution approach is as follows….

  • OAAM policy will set risk score (in Post Authentication Checkpoint) based on client’s geo location. i.e. If the client’s geo location is matching with policy/rule configuration, OAAM will set risk level/score to some specific number.
  • OAAM will then pass the score (generated from Post Authentication Checkpoint) as an Identity Context to OAM.
  • OAM will get the Identity Context (set by OAAM) and it will set an authentication response session attribute according to the Identity Context. i.e. As Authentication Response in OAM, values from IdentityContext will be stored in session attributes. The session attributes can be checked by OAM Authorization policies.
  • OAM Authorization policy will take decision (allow or deny) based on the rule/condition configured to check risk score available from session attributes (set by OAM Authentication response)

Out-of-the-box polices in OAAM generate risk scores like 100, 200, 300, 500 and OAM Rule/Condition in Authorization policy allows string comparison on session attribute with operators such as “equals”, “starts-with”, “contains” and “ends-with”. Our new policy in OAAM can generate score like 1 for client IP address of ABC Countries and 0 for client IP address of XYZ Countries. So with new OAAM policy in place in as a Post Authentication Checkpoint, risk scores will be like 101, 201, 301,… for client IP address of ABC Countries. This will allow us to configure OAM Rule/Condition in Authorization policy to check risk score with the “ends-with” operator.

Risk Score generated by OAAM Checkpoint execution will be available from Identity Context. So, OAAM polices can be configured in a way to generate risk scores in specific way and accordingly, OAM Rule/Condition in Authorization policy can be configured to take appropriate action based on the risk score. Above mentioned logic is just one example to add 1 or 0 to risk score from OAAM policies.

Following are the steps/changes for above mentioned solution approach for the example use case. These steps are only to give the basic understanding of the configuration to meet the requirements. Important steps/changes to note here from the perspective of Identity Context are about the way Authentication Response configuration is used to save values in session variables and use the same during Authorization.

A)

Configure OAM-OAAM integration using TAPScheme (documentation)

B)

Configure OAM and OAAM for Identity Context (documentation)

  • Change TapTokenVersion to v2.1 in OAM (oam-config.xml). If Thirdparty TAP Partner is yet to be registered in OAM, with WLST execution of “registerThirdPartyTAPPartner”, parameter tapTokenVersion=”v2.1″ can be used to avoid manual changes in oam-config.xml
  • Update / Add configuration parameter in OAAM (Properties section of OAAM Admin Console). oaam.uio.oam.dap_token.version=v2.1

C)

In OAAM, update Groups/Policies configuration to generate required risk score

  • Create a policy in OAAM with two rules to generate risk score 0 (for request from XYZ Countries on in other words, NOT from ABC Countries) or 1 (for request from ABC Countries)
    • Create a group in OAAM to contain countries ABC. This group will be used in Rules we will add to new OAAM policy.
    • Add ABC Countries to the group.
    • Create a group in OAAM to contain countries XYZ. This group will be used in Rules we will add to new OAAM policy.
    • Add XYZ Countries to the group.
    • Create a new OAAM policy for checkpoint “Post authentication”.
    • Associate the policy with “All Users” so that the policy is executed for each post authentication checkpoint execution
    • Add a new rule “Request from ABC Countries” to policy “TEST: Policy to return specific risk score” for checking request from ABC Countries.
    • Add a condition “Location: In Country group” to rule “Request from ABC Countries”
    • Update the condition with correct value for parameters “Is in group” and “Country in country group”. Selected country group which was created in previous steps.
      Rule - Request from ABC
    • Update result for the rule “Request from ABC Countries” to generate score 1
    • Add a new rule “Request from XYZ Countries” (in other words, NOT from ABC Countries) to policy “TEST: Policy to return specific risk score” for checking request from XYZ Countries (in other words, NOT from ABC Countries).
    • Add a condition “Location: In Country group” to rule “Request from XYZ Countries” (in other words, NOT from ABC Countries)
    • Update the condition with correct value for parameters “Is in group” and “Country in country group”. Selected country group which was created in previous steps.
      Rule - Request from XYZ
      • or
        Rule - Request from XYZ (Not from ABC)
    • Update result for the rule “Request from XYZ Countries” (in other words, NOT from ABC Countries) to generate score 0
    • Policy with two rules and policy linked to all users to be executed for each post authentication checkpoint execution…
      Policy with two rules..

D)

In OAM, Update Authentication Policy to store OAAM risk score/level in session attribute

  • Add an Identity Context Response in the OAM Authentication Policy
    • Navigate to the Application Domain of the required application.
    • From the Authentication Policies tab select the respective protected policy.
    • From the Responses tab create a new response as follows (Name the response accordingly and write it down because it will be used in the authorization policy). Variable $session.attr.risk.level of Identity Context would be having risk score set by OAAM
      OAM AuthN Policy

E)

In OAM, Update Authorization Policy to Allow or Deny based on value for session attribute created in Authentication Policy

  • Update Authorization Policy to take decision based on the session attribute created in Authentication Policy
    • Navigate to the Application Domain of the required application.
    • Navigate to the Authorization Policies tab and select the Protected policy specific for the application needing geo location authorization.
    • Select the Conditions tab and create a new condition. Name the condition as needed to relate to the ABC Countries (risk score ending with 1) requirement. Normally OAAM returns risk scores like 100, 200, 300, 500, so note the Operator is set to “Ends with” because say OAAM returns a risk score of 300, then if the user is coming from the ABC Countries, it will add “1” and the finaly score could be 301. Therefore using the Operator “Ends With” and an Attribute Value of “1”, the score would see 301 as a match and determine the user is coming from the geo location of the ABC Countries.OAM AuthZ Policy B
    • You can repeat Condition creation for for another Condition if you want to create a rule for XYZ Countries (risk score ending with 0). OAM AuthZ Policy A
    • You should have the needed Conditions created now (Note your condition names may be different). Note if you need a XYZ Countries Condition you can repeat the creating a Condition and set the value to zero, or Ends With zero. This Condition could be used to Deny or Allow access based on NOT being in the ABC Countries.
    • Select the Rules tab in the Authorization Policy and configure the selected Conditions as needed. For example you could add the Condition ABC Countries to the Allow Rule for the Selected Condition. This affect would ALLOW a user IF they connected from the ABC CountriesABC Countries based on OAAM risk score asserted as an Identity Context to OAM.
      OAM AuthZ Policy Rules

OAAM_SAMPLE with different integration and/or deployment options

Next: OAM Federation: Identity Provider & Service Provider Management
Previous: Using OAAM Risk Evaluation in OAM Authorization Policies
$
0
0

Multiple times in past, I have encountered questions/issues about OAAM_SAMPLE. So, thought to write a small post explaining how it can be used/configured to test (try out) different native integration options for OAAM.

The OAAM Sample application is for demonstration purposes to familiarize yourself with OAAM APIs. It is not intended to be used as production code since it only provides basic elements of API usage. If you are implementing a native integration, you can develop your application using the OAAM Sample application as a reference.

For understanding the Flow and OAAM APIs, it would be very helpful to play around with OAAM Sample Application. Following are the few use cases where OAAM Sample Application will be useful in performing proof of concepts around native integration of OAAM APIs with protected business application.

  • To analyze behavior of OAAM APIs
  • To analyze and develop Custom Fingerprinting
  • To analyze and develop Custom Challenge Flow
  • To analyze and develop flows around Virtual Authentication Devices, Knowledge-Based Authentication, and One-Time Password
  • To analyze and develop integration of Client Applications with OAAM for Transactions/Entities

Through this post, I am intending to provide details about following integration and/or deployment scenarios. Considering the popularity and usage, Java based native integration/deployment options are mentioned here in this post.

  • Integration Scenarios/Options
    • Native SOAP Integration
    • Native In-Proc (static linking) Integration
  • Deployment Scenarios/Options
    • Native SOAP or In-Proc Integration using OAAM Shared Library on WebLogic
    • Native SOAP or In-Proc Integration on Non-WebLogic containers
    • Native Integration for Transactions / Entities

As example of native integration, OAAM Sample Application can be considered as protected application on which OAAM based risk evaluation and prevention is required.

Native In-Proc (static linking) Integration:

OAAM can be natively integrated with application(s) to provide extreme high performance and highly customizable security (risk evaluation and prevention). This native integration embeds OAAM in-process inside the protected applications. The application invokes the OAAM APIs directly to access risk and challenge flows. This integration involves inclusion of OAAM core libraries (Jar files) and properties files into protected application. As OAAM is embedded in application(s) for this integration, this would even require OAAM database access from protected applications.

Considering the performance (in compare to SOAP integration), In-Proc integration would be considered better but from the perspective of maintainability/patching, In-Proc integration would  be a bit complicated.

Native SOAP Integration:

Customers who have advanced requirements similar to native integration but who prefer to use SOAP web services instead of Java API integration directly can choose this option.

This is widely used integration option which involves inclusion of OAAM SOAP Client Library (Java/.Net Wrapper to invoke SOAP APIs) to have communication with OAAM Server for device fingerprinting, risk evaluation and KBA related activities.

OAAM_SAMPLE package is available from:

Brief instructions for setting up the OAAM Sample application are available from Developer’s Guide for OAAM. The most recent OAAM Sample Application that illustrates Java API integration can be downloaded from MOS. MOS Doc ID 1542025.1 is having reference to OAAM Sample package for 11.1.2.x and the same is used while writing this post.

Native SOAP Integration

Following are the few important aspects / configuration steps to understand and keep in mind for SOAP based native integration.

  • OAAM Server (default name of managed server: oaam_server_server1 and the name of Enterprise Application oaam_server.ear) exposes WebServices for SOAP based integration.
  • WSDL for the exposed WebServices can be found from http://<OAAM Server Host>:<Port>/oaam_server/services?wsdl
  • As OAAM provides client library for native integration, it is highly advisable to use the same and avoid usage of WebServices directly (i.e. without using client library provided by OAAM).
  • When OAAM Shared Library are not used, it would be advisable to replace oaam_soap_client.jar and bharosa_properties folder with files available from <IAM_ORACLE_HOME>/oaam/oaam_libs/jar/oaam_soap_client.jar and <IAM_ORACLE_HOME>/oaam/oaam_libs/war/oaam_native_lib.war/WEB-INF/classes/bharosa_properties.
  • All the changes in configurable properties should be included in oaam_custom.properties. By default, there are lot of properties already set in oaam_custom.properties and some of them would be required to be corrected/deleted based on integration and deployment scenario.
  • Based on following configurable property, OAAM SOAP Client would use WebLogic based SOAP Implementation. For usage of different SOAP Implementation (like AXIS), customized implementation of VCryptSOAP (like VCryptSOAPGenericImpl) would be required to be prepared and configured.
    • vcrypt.common.util.vcryptsoap.impl.classname=com.bharosa.vcrypt.common.impl.VCryptSOAPGenericImpl
  • Same OAAM Client Library can be used for SOAP or In-Proc integration. To let OAAM Client Library know to use SOAP based integration, following properties are required to be set correctly in oaam_custom.properties:
    • vcrypt.tracker.soap.useSOAPServer=true
    • vcrypt.soap.disable=false
    • vcrypt.tracker.impl.classname=com.bharosa.vcrypt.tracker.impl.VCryptTrackerSOAPImpl
    • vcrypt.tracker.soap.url=http://host-name:port/oaam_server/services
  • OAAM Client library can read configuration parameters from Database and Properties files. In most of the deployment scenarios, OAAM Sample will not be having access to Database. So to let OAAM Client know to read configurable parameters only from Properties Files, following properties are required to be set in oaam_custom.properties:
    • bharosa.config.impl.classname=com.bharosa.common.util.BharosaConfigPropsImpl
    • bharosa.config.load.impl.classname=com.bharosa.common.util.BharosaConfigLoadPropsImpl
  • Default SOAP Implementation (VCryptSOAPGenericImpl) is designed to use BASIC (username and password) based HTTP Authentication. Following configurable properties are required to be set in oaam_custom.properties to have Authentication enabled for SOAP communication. Keystore related details are available from standard documentation : Setting Up Client Side Keystore to Secure the SOAP User Password.
    • vcrypt.soap.auth=true
    • vcrypt.soap.auth.keystorePassword=<Java-keystore-password>
    • vcrypt.soap.auth.aliasPassword=<Keystore-alias-password>
    • vcrypt.soap.auth.username=<SOAP-User-name>
    • vcrypt.soap.auth.keystoreFile=<Keystore File name which should be available from classpath. i.e. WEB-INF/classes>
  • For configuring Authorization on OAAM Server side (exposing WebServices), details are available from post: How to secure Web Services exposed by OAAM Server.
  • OAAM uses encryption/decryption for Configurable properties and some Database Tables/Columns. Algorithm and Implementation for such encryption/decryption is controlled by few configurable properties which will be first read during initialization of OAAM Client.
    • By default, required configuration for such encryption/decryption is read from CSF (which would have been initialized during first startup of OAAM Server/Admin). So, if the deployment of OAAM Sample application is on the same WebLogic Server domain where OAAM Server is running, then there should not be any “bharosa.cipher.encryption.algorithm.enum*” properties set in oaam_custom.properties.
    • But, if the deployment of OAAM Sample application is on a non-WebLogic Server or a non-Identity Access Management WebLogic Server domain, then following properties should be set in oaam_custom.properties:
      • bharosa.cipher.encryption.algorithm.enum.DESede_config.keyRetrieval.classname=com.bharosa.common.util.cipher.KeystoreKeyRetrieval
      • bharosa.cipher.encryption.algorithm.enum.DESede_config.keystoreFile=<Keystore File name which should be available from classpath. i.e. WEB-INF/classes>
      • bharosa.cipher.encryption.algorithm.enum.DESede_config.keystorePassword=<Java-keystore-password>
      • bharosa.cipher.encryption.algorithm.enum.DESede_config.aliasPassword=<Keystore-alias-password>
      • bharosa.cipher.encryption.algorithm.enum.DESede_db.keyRetrieval.classname=com.bharosa.common.util.cipher.KeystoreKeyRetrieval
      • bharosa.cipher.encryption.algorithm.enum.DESede_db.keystoreFile=<Keystore File name which should be available from classpath. i.e. WEB-INF/classes>
      • bharosa.cipher.encryption.algorithm.enum.DESede_db.keystorePassword=<Java-keystore-password>
      • bharosa.cipher.encryption.algorithm.enum.DESede_db.aliasPassword=<Keystore-alias-password>
  • Based on the preference, EAR or WAR should be prepared including updated properties and library files.
  • Based on the deployment scenario, there would be few more properties required to be updated. Such changes are mentioned in the sections below.

Considering/Understanding of above mentioned points and documentation should make the deployment of OAAM Sample easier.

Native In-Proc (static linking) Integration

Following are the few important aspects / configuration steps to understand and keep in mind for In-Proc (static linking) native integration.

  • Same OAAM Sample package would be capable enough to work with SOAP or In-Proc integration. There would be changes required in configurable properties and libraries to use specific integration (SOAP or In-Proc) with OAAM Sample.
  • With In-Proc integration, OAAM Client library will directly invoke Java APIs (without SOAP Client) and that would require Database access from OAAM Client. i.e. OAAM Client will need access to OAAM Core Libraries and Data Source. Considering such access, it would be advisable to use OAAM Shared Library and Data Source on WebLogic. If in-proc integration is used with non-weblogic container, OAAM Sample deployment would need to include changes in persistence (database access) layer and OAAM core libraries.
  • All the changes in configurable properties should be included in oaam_custom.properties. By default, there are lot of properties already set in oaam_custom.properties and some of them would be required to be corrected/deleted based on integration and deployment scenario.
  • Same OAAM Client Library can be used for SOAP or In-Proc integration. To let OAAM Client Library know to use In-Proc integration, following properties are required to be set correctly in oaam_custom.properties:
    • vcrypt.tracker.soap.useSOAPServer=false
    • vcrypt.soap.disable=true
  • OAAM Client library can read configuration parameters from Database and Properties files. In In-Proc integration, OAAM Sample will be having access to Database and Properties files both. So, following properties should not be set in oaam_custom.properties:
    • bharosa.config.impl.classname
    • bharosa.config.load.impl.classname
  • OAAM uses encryption/decryption for Configurable properties and some Database Tables/Columns. Algorithm and Implementation for such encryption/decryption is controlled by few configurable properties which will be first read during initialization of OAAM Client.
    • By default, required configuration for such encryption/decryption is read from CSF (which would have been initialized during first startup of OAAM Server/Admin). So, if the deployment of OAAM Sample application is on the same WebLogic Server domain where OAAM Server is running, then there should not be any “bharosa.cipher.encryption.algorithm.enum*” properties set in oaam_custom.properties.
    • But, if the deployment of OAAM Sample application is on a non-WebLogic Server or a non-Identity Access Management WebLogic Server domain, then following properties should be set in oaam_custom.properties:
      • bharosa.cipher.encryption.algorithm.enum.DESede_config.keyRetrieval.classname=com.bharosa.common.util.cipher.KeystoreKeyRetrieval
      • bharosa.cipher.encryption.algorithm.enum.DESede_config.keystoreFile=<Keystore File name which should be available from classpath. i.e. WEB-INF/classes>
      • bharosa.cipher.encryption.algorithm.enum.DESede_config.keystorePassword=<Java-keystore-password>
      • bharosa.cipher.encryption.algorithm.enum.DESede_config.aliasPassword=<Keystore-alias-password>
      • bharosa.cipher.encryption.algorithm.enum.DESede_db.keyRetrieval.classname=com.bharosa.common.util.cipher.KeystoreKeyRetrieval
      • bharosa.cipher.encryption.algorithm.enum.DESede_db.keystoreFile=<Keystore File name which should be available from classpath. i.e. WEB-INF/classes>
      • bharosa.cipher.encryption.algorithm.enum.DESede_db.keystorePassword=<Java-keystore-password>
      • bharosa.cipher.encryption.algorithm.enum.DESede_db.aliasPassword=<Keystore-alias-password>
  • Based on the preference, EAR or WAR should be prepared including updated properties and library files.
  • Based on the deployment scenario, there would be few more properties required to be updated. Such changes are mentioned in the sections below.

Considering/Understanding of above mentioned points and documentation should make the deployment of OAAM Sample easier.

Native SOAP or In-Proc Integration using OAAM Shared Library on WebLogic

Apart from the details mentioned above about SOAP or In-Proc integration, following are the few additionally important aspects / steps for deployment of OAAM Sample on WebLogic and to use specific integration for invocation of OAAM APIs.

  • There are two versions (EAR and WAR) of OAAM Shared Library (oaam_native_lib) available from <IAM_ORACLE_HOME>/oaam/oaam_libs/ear or <IAM_ORACLE_HOME>/oaam/oaam_libs/war. Target for Shared Library should be updated correctly to make sure that OAAM Sample Application would be able to access that.
    • If OAAM Sample is packaged (and to be deployed) as WAR, WAR version of oaam_native_lib (<IAM_ORACLE_HOME>/oaam/oaam_libs/war/oaam_native_lib.war) should be deployed as shared library in WebLogic.
      • To use WAR version of Shared Library from OAAM Sample Web Application, you must refer to the shared library by adding the following entry to your WebLogic deployment descriptor file, weblogic.xml:
        • <library-ref>
                 <library-name>oracle.oaam.libs</library-name>
          </library-ref>
    • If OAAM Sample is packaged (and to be deployed) as EAR, EAR version of oaam_native_lib (<IAM_ORACLE_HOME>/oaam/oaam_libs/ear/oaam_native_lib.ear) should be deployed as shared library in WebLogic.
      • To use WAR version of Shared Library from OAAM Sample Enterprise Application, you must refer to the shared library by adding the following entry to your WebLogic deployment descriptor file, weblogic-application.xml:
        • <library-ref>
                 <library-name>oracle.oaam.libs</library-name>
          </library-ref>
  • As Shared Library is including OAAM libraries/jars and properties, Sample application would NOT need to include any OAAM specific libraries/jars and properties files. Sample application would just need to include oaam_custom.properties in WEB-INF from OAAM Sample integration perspective.
  • In case of In-Proc integration, Target for Data Source jdbc/OAAM_SERVER_DB_DS should also be updated correctly to make sure that OAAM Sample Application would be able to access that. If OAAM Sample is to be deployed on non-Identity Access Management WebLogic Server domain, creation of Data Source (with name jdbc/OAAM_SERVER_DB_DS) would be required to provide database access to In-Proc integration.
  • If OAAM Sample is to be deployed on non-Identity Access Management WebLogic Server domain, values for following Keys in CSF (of WebLogic Domain for OAAM Sample) should exactly match with the values in CSF of Identity Access Management WebLogic Server domain.
  • If OAAM Sample application is to be deployed on same domain as OAAM Server/Admin, it would be advisable to deploy OAAM Sample as EAR. Default installation of OAAM will include deployment of OAAM Shared Library (oracle.oaam.libs) as well and the Shared Library would be deployed as EAR. If OAAM Sample is deployed as WAR on the same domain, it would not be able to access EAR Shared Library.
  • Following are the few properties which are updated in oaam_custom.properties to make OAAM Sample work with SOAP based integration.
    • 2c2
      < vcrypt.tracker.soap.url=http://${hostName}:${webapp_port}/oaam_server/services
      ---
      > vcrypt.tracker.soap.url=http://myhostedlinux:14300/oaam_server/services
      4c4
      < vcrypt.soap.auth=false
      ---
      > vcrypt.soap.auth=true
      9c9
      < vcrypt.soap.auth.username=dove
      ---
      > vcrypt.soap.auth.username=oaamsoap
      30c30
      < bharosa.image.dirlist=<Weblogic Folder>/Oracle_IDM1/oaam/oaam_images/
      ---
      > bharosa.image.dirlist=/scratch/orafmw/r2ps2/products/access/iam/oaam/oaam_images/
  • Following are the few properties which are updated in oaam_custom.properties to make OAAM Sample work with In-Proc based integration.
    • 2c2
      < vcrypt.tracker.soap.url=http://${hostName}:${webapp_port}/oaam_server/services
      ---
      > #vcrypt.tracker.soap.url=http://iam11g.local:14300/oaam_server/services
      7,10c7,10
      < vcrypt.soap.auth.keystorePassword=ZG92ZTEyMzQ=
      < vcrypt.soap.auth.aliasPassword=ZG92ZTEyMw==
      < vcrypt.soap.auth.username=dove
      < vcrypt.soap.auth.keystoreFile=system_soap.keystore
      ---
      > #vcrypt.soap.auth.keystorePassword=ZG92ZTEyMzQ=
      > #vcrypt.soap.auth.aliasPassword=ZG92ZTEyMw==
      > #vcrypt.soap.auth.username=oaamsoap
      > #vcrypt.soap.auth.keystoreFile=system_soap.keystore
      13c13
      < vcrypt.common.util.vcryptsoap.impl.classname=com.bharosa.vcrypt.common.impl.VCryptSOAPGenericImpl
      ---
      > #vcrypt.common.util.vcryptsoap.impl.classname=com.bharosa.vcrypt.common.impl.VCryptSOAPGenericImpl
      16,19c16,19
      < vcrypt.soap.disable=false
      < vcrypt.tracker.soap.useSOAPServer=true
      < vcrypt.tracker.impl.classname=com.bharosa.vcrypt.tracker.impl.VCryptTrackerSOAPImpl
      < vcrypt.soap.call.timeout=10000
      ---
      > vcrypt.soap.disable=true
      > vcrypt.tracker.soap.useSOAPServer=false
      > #vcrypt.tracker.impl.classname=com.bharosa.vcrypt.tracker.impl.VCryptTrackerSOAPImpl
      > #vcrypt.soap.call.timeout=10000
      21,22c21,22
      < bharosa.config.impl.classname=com.bharosa.common.util.BharosaConfigPropsImpl
      < bharosa.config.load.impl.classname=com.bharosa.common.util.BharosaConfigLoadPropsImpl
      ---
      > #bharosa.config.impl.classname=com.bharosa.common.util.BharosaConfigPropsImpl
      > #bharosa.config.load.impl.classname=com.bharosa.common.util.BharosaConfigLoadPropsImpl
      30c30
      < bharosa.image.dirlist=<Weblogic Folder>/Oracle_IDM1/oaam/oaam_images/
      ---
      > bharosa.image.dirlist=/scratch/orafmw/r2ps2/products/access/iam/oaam/oaam_images/
      33,41c33,41
      < bharosa.cipher.encryption.algorithm.enum.DESede_config.keyRetrieval.classname=com.bharosa.common.util.cipher.KeystoreKeyRetrieval
      < bharosa.cipher.encryption.algorithm.enum.DESede_config.keystoreFile=system_config.keystore
      < bharosa.cipher.encryption.algorithm.enum.DESede_config.keystorePassword=ZG92ZTEyMzQ=
      < bharosa.cipher.encryption.algorithm.enum.DESede_config.aliasPassword=ZG92ZTEyMw==
      <
      < bharosa.cipher.encryption.algorithm.enum.DESede_db.keyRetrieval.classname=com.bharosa.common.util.cipher.KeystoreKeyRetrieval
      < bharosa.cipher.encryption.algorithm.enum.DESede_db.keystoreFile=system_db.keystore
      < bharosa.cipher.encryption.algorithm.enum.DESede_db.keystorePassword=ZG92ZTEyMzQ=
      < bharosa.cipher.encryption.algorithm.enum.DESede_db.aliasPassword=ZG92ZTEyMw==
      ---
      > #bharosa.cipher.encryption.algorithm.enum.DESede_config.keyRetrieval.classname=com.bharosa.common.util.cipher.KeystoreKeyRetrieval
      > #bharosa.cipher.encryption.algorithm.enum.DESede_config.keystoreFile=system_config.keystore
      > #bharosa.cipher.encryption.algorithm.enum.DESede_config.keystorePassword=ZG92ZTEyMzQ=
      > #bharosa.cipher.encryption.algorithm.enum.DESede_config.aliasPassword=ZG92ZTEyMw==
      > #
      > #bharosa.cipher.encryption.algorithm.enum.DESede_db.keyRetrieval.classname=com.bharosa.common.util.cipher.KeystoreKeyRetrieval
      > #bharosa.cipher.encryption.algorithm.enum.DESede_db.keystoreFile=system_db.keystore
      > #bharosa.cipher.encryption.algorithm.enum.DESede_db.keystorePassword=ZG92ZTEyMzQ=
      > #bharosa.cipher.encryption.algorithm.enum.DESede_db.aliasPassword=ZG92ZTEyMw==

Native SOAP or In-Proc Integration using OAAM Shared Library on Non-WebLogic containers

Apart from the details mentioned above about SOAP or In-Proc integration, following are the few additionally important aspects / steps for deployment of OAAM Sample on Non-WebLogic containers like Apache Tomcat and to use specific integration for invocation of OAAM APIs.

  • As on Non-Weblogic containers, there would not be OAAM Shared Library available so all required OAAM Client Libraries (Jar files) and properties files should be included in the OAAM Sample Application.
  • For In-Proc integration, OAAM Core Libraries (Jar files) and properties files should be included in the OAAM Sample Application.
  • For In-Proc integration, there would be changes required in libraries, properties files and persistence.xml to make database accessible from OAAM Sample. Changes required for this would vary based on the Application Container. As example, following are the changes required in OAAM Sample to make it work with In-Proc integration from Non-Weblogic container like Apache Tomcat
    • Additional Changes in Properties (oaam_custom.properties):
      • oaam.db.toplink.useCredentialsFromCSF=false
      • oaam.csf.useMBeans=false
    • Changes in META-INF/persistence.xml:
      •             <property name=”eclipselink.jdbc.url” value=”jdbc:oracle:thin:@myhostedlinux:1521:iam111220″/>
      •             <property name=”eclipselink.jdbc.user” value=”AM_OAAM”/>
      •             <property name=”eclipselink.jdbc.password” value=”oracle123″/>
    • Inclusion of additional libraries (Jar files) in Classpath:
      • com.bea.core.antlr_2.7.7.jar, com.bea.core.apache.commons.collections_3.2.0.jar  , jps-api.jar, jps-manifest.jar, jps-az-management.jar, jps-platform.jar, jps-az-rt.jar, jps-se.jar, jacc-spi.jar, jps-ee.jar, jps-internal.jar, jps-common.jar, com.oracle.toplink_1.1.0.0_11-1-1-6-0.jar, eclipselink.jar, javax.persistence_1.1.0.0_2-0.jar, ojdbc6.jar, commons-codec-1.2.jar, drools-base-2.0-beta-21.jar, drools-core-2.0-beta-21.jar, drools-io-2.0-beta-21.jar, drools-java-2.0-beta-21.jar, drools-jsr94-2.0-beta-21.jar, drools-smf-2.0-beta-21.jar, groovy-all-1.6.3.jar, janino-2.0.16.jar, jsr94.jar, oaam_core.jar, oaam_native_wrapper.jar, oaam_uio.jar, etc…
    • Inclusion of additional configuration files in Classpath:
      • oaam_toplink_orm.xml and META-INF/persistence.xml

 

Native Integration for Transactions / Entities

With OAAM Sample Application, it’s very much easy to play around with OAAM APIs for Entities and Transactions. With changes in configurable properties, OAAM Sample will be able to render custom input forms for entities and transactions. Links available on the left side (after logging in successfully) are rendered based on the configurable properties.

Values for following enumerations in oaam_custom.properties are responsibile for rendering input pages for transactions and entities.

  • tracker.entity.type.enum
  • tracker.entity.form.enum.<xyz>.form_fields
  • tracker.entity.form_field.<xyz>.enum
  • tracker.transaction.type.enum
  • tracker.transaction.form.enum.<xyz>.form_fields
  • tracker.transaction.form_field.<xyz>.enum

 

OAM Federation: Identity Provider & Service Provider Management

Next: OAM Federation 11.1.2.3: Performing a Loopback Test
Previous: OAAM_SAMPLE with different integration and/or deployment options
$
0
0

In this blog post I want to clarify a point of initial confusion some people experience with OAM Federation 11.1.2.3. If we go to the “Federation” tab of the OAM Console, we see:

LaunchPadScreenShot

Now the two main objects you manage in your OAM Fed configuration are your IdP Partner definitions and your SP Partner definitions. So, I want to look at the IdP Partner definitions. Which link do I choose? The answer is, “Service Provider Management”. Conversely, to look at the SP Partner definitions, I click on “Identity Provider Management”. To many people, that at first seems back-to-front, but if you think about it some more, it makes perfect sense.

Let’s draw a diagram:

SAMLDiagram

Each Service Provider has a relationship with one or more Identity Providers, and each Identity Provider has a relationship with one or more Service Providers. The owner of each Service Provider has to decide which Identity Providers it is willing to work with, and the owner of each Identity Provider has to decide which Service Providers it is willing to work with. Each of these IdP-SP relations can only exist by mutual agreement of both ends; each side is trusting the other – the service provider needs to trust the identity provider to provide genuine user identities (i.e. only authenticate joe@example.com if it really is Joe); the identity provider needs to trust the service provider not to abuse the identities it is sent (e.g. to maintain the confidentiality of the user attribute data it is sent).

So the most important thing each IdP needs to know is – which SPs am I authorised to talk to? And the most important thing each SP needs to know is — which IdP am I authorized to talk to? So the SP Partners are part of the IdP configuration, and the IdP Partners are part of the SP configuration.

OAM Federation 11.1.2.3: Performing a Loopback Test

Next: OAM Federation 11.1.2.3: Example Message Processing Plugin
Previous: OAM Federation: Identity Provider & Service Provider Management
$
0
0

In this blog post I will share steps for performing a loopback test of OAM Federation 11.1.2.3. In a loopback test, we configure OAM’s SP to point to OAM’s IdP. This enables you to confirm the basic functionality of OAM Federation without requiring any external partner server. I also find it useful in plugin development – you can perform initial development of your plugin using just the OAM Federation server, since you might not have an instance of the intended partner server available in your development environment.

You can find instructions here on how to do the same thing in OIF 11.1.1.x federation. (Those instructions are for Fusion Apps, however the loopback test itself is identical for non-Fusion Apps environments.) You’ll find the steps in OAM 11.1.2.3 are very similar, the main difference being that OAM 11.1.2.3 uses OAM Console for configuration rather than Enterprise Manager. Also, while I have provided steps for OAM 11.1.2.3, the steps in 11.1.2.2 are very similar (the configuration screens themselves are similar, but the navigation paths to reach them are different).

A couple of prerequisites:

  • you need OAM 11.1.2.3 installed. I used the Lifecycle Management Tools Deployment Wizard — see 11.1.2.3 IAM Deployment Guide
  • you need the “Identity Federation” service enabled. If it is not already enabled, you can go to oamconsole > Configuration tab > Available Services. (Hint: if it is disabled yet the “Enable Service” link is greyed out, try disabling then re-enabling “Mobile & Social”).

Download the metadata

OAM’s IDP metadata is available using the URL: http://OAMHOST:OAMPORT/oamfed/idp/metadata

Download that and save it to a file.

You can also download the SP metadata from the URL: http://OAMHOST:OAMPORT/oamfed/sp/metadata

However, what you will discover, is they are basically the same thing, with only the ID, timestamps, and digest/signature values different. To see this, run each XML file through xmllint –format, and then diff the results.

Hence, in OAM Federation’s case, we can treat the two sets of metadata interchangeably, and only need to save the one file.

Next we need to create LoopbackIDP

oamconsole > Federation tab > under “Federation” select “Service Provider Management”
Click on “Create Identity Provider Partner”:

Fill in the following data:

  • Name: “LoopbackIDP”
  • “Enable Partner” will be checked by default
  • Select protocol “SAML2.0”, browse to the metadata XML file you saved previously
  • Under “User Identity Store” you can select “OAMIDSTORE”.
  • You can leave the other mapping settings, e.g. “Map assertion Name ID to User ID Store attribute”, to their defaults. Basically, you can use whatever attribute you want, provided you have that attribute defined and unique for your test users, and you make the same configuration at the other end.

Click Save – LoopbackIDP will be created.

 

Now to test this, let’s use the SP test page:

The SP Test page can be accessed via: http://OAMHOST:OAMPORT/oamfed/user/testspsso

 

initially this screen will display “System Error”.

If you look at the logs (e.g. wls_oam1-diagnostic.log) you will see:

oracle.security.fed.event.EventException: SP Engine error - the Test SP Engine is not enabled
at oracle.security.fed.eventhandler.fed.authn.engines.testsp.TestSPRetrieveInformationEventHandler.perform(TestSPRetrieveInformationEventHandler.java:77)

Solution: you need to run the configureTestSPEngine("true") command in WLST:

  • Start WLST:
 $IAM_ORACLE_HOME/common/bin/wlst.sh
    • Note that there are multiple copies of WLST installed. You need to use the copy under the $IAM_ORACLE_HOME, since that copy has the configureTestSPEngine() command configured. The other copies of WLST installed in the other homes (oracle_common, wlserver_10.3) will lack this command, and the other OAM-specific commands.
  • Connect to the WLS Admin server:
 connect()

Enter the username (e.g. weblogic) ,password & Admin Server URL (e.g. t3://myadminserver.example.com:7001 )

  • Navigate to Domain Runtime branch:
domainRuntime()
  • Execute the configureTestSPEngine() command: configureTestSPEngine(“true”)

 

Now we try again:

Choose partner “LoopbackIDP” and “Start SSO”.

Once again we get a “System Error”. Looking at the logs:

<Error> <oracle.security.fed.jvt.JVTDiscoveryManager> <FEDSTS-12014> <Discovery Finder Exception: unable to locate object in the repository: {0}
oracle.security.fed.jvt.discovery.exceptions.DiscoveryFinderException: Missing partner configuration for: http://OAMHOST:OAMPORT/oam/fed
at oracle.security.fed.jvt.discovery.model.config.ConfigServiceDiscoveryProvider.getPartnerConfig(ConfigServiceDiscoveryProvider.java:1043)
at oracle.security.fed.jvt.discovery.model.config.ConfigServiceDiscoveryProvider.locateProtocolConfiguration(ConfigServiceDiscoveryProvider.java:910)
at oracle.security.fed.jvt.discovery.model.config.CSFConfigDiscoveryProvider.locateProtocolConfiguration(CSFConfigDiscoveryProvider.java:134)
at oracle.security.fed.jvt.discovery.model.config.ChainingConfigDiscoveryProvider.locateProtocolConfiguration(ChainingConfigDiscoveryProvider.java:42)
at oracle.security.fed.jvt.discovery.model.config.CachingConfigDiscoveryProvider.locateProtocolConfiguration(CachingConfigDiscoveryProvider.java:75)
at oracle.security.fed.jvt.JVTDiscoveryManager.locateProtocolConfiguration(JVTDiscoveryManager.java:1956)

This is because we have configured “LoopbackIDP” as an IDP partner in the SP configuration, but we have not configured the SP as an SP partner in the IDP configuration. Let us do that now:

Next we need to create LoopbackSP

oamconsole > Federation tab > under “Federation” select “Identity Provider Management”

Click on “Create Service Provider Partner”:

Fill in the following data:

  • Name: “LoopbackSP”
  • “Enable Partner” will be checked by default
  • Select protocol “SAML2.0”, browse to the metadata XML file you saved previously
  • For “NameID Format” you can use the default of “Email Address”. For “NameID Value” you can use “User ID Store Attribute” of “mail”.
  • Other settings can be left at their defaults.

Click Save – LoopbackSP will be created.

 

Now let’s repeat the test with the test SP app:

Having tested this with an SP app, we can now do the same test using a protected page:

 

  • In oamconsole, go to Federation tab, Federation tile, Service Provider Management
  • Search for LoopbackIDP and open it
  • Click “Create Authentication Scheme and Module”

This will create an Authentication Module called LoopbackIDPFederationPlugin and an Authentication Scheme called LoopbackIDPFederationScheme

  • Go to your OHS htdocs directory — if you used LCM installation, this is $IDMTOP/config/instances/ohs1/config/OHS/ohs1/htdocs
  • Create a directory called fedtest
  • Inside fedtest create a file called index.html, add some content e.g. “<h1>Hello World!</h1>”
  • In OAM Console, go to “Application Security” tab, “Access Manager” tile, “Application Domains” link:

  • Then press “Search”:
  • Open “IAM Suite”:
  • Go to “Authentication Policies” tab, and click “Create”:

  • On the “Create Authentication Policy” screen, enter name “LoopbackIDPAuthPolicy” and select “Authentication Scheme” of “LoopbackIDPFederationScheme”. Then click “Apply”.

Go back to the “IAM Suite” tab, then select the “Resources” subtab. Click “Create”:

Choose resource type of “HTTP”, host identifier of “IAMSuiteAgent”, Resource URL of /fedtest/…/*


And protection level of “Protected”, with “Authentication Policy” of “LoopbackIDPAuthPolicy” and “Authorization Policy” of “Protected Resource Policy”

Click Apply

 

  • Now finally to test: open a new Private Browsing Window, and navigate to http://OAMHOST:OAMPORT/fedtest/index.html . You should get redirected to the login page, and you should see /oamfed/idp/samlv20 in the address bar of the login page. This shows we are using SAML. Then login and you should see the message “Hello World!”

 

 


OAM Federation 11.1.2.3: Example Message Processing Plugin

Next: OAM Federation 11.1.2.3: Performing a loopback test with WS-Federation
Previous: OAM Federation 11.1.2.3: Performing a Loopback Test
$
0
0

SAML is an extensible protocol. Since it is based on XML, through the use of XML namespaces, custom elements and attributes can be inserted into the SAML messages at the appropriate places. Sometimes third party or custom SAML implementations will require particular custom elements or attributes to function.

In this example, we will suppose an IdP requires a custom <CompanyInfo> element included in the SAML extensions to provide the name of the company issuing the SAML request:

<samlp:Extensions xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol">
<CompanyInfo xmlns="http://example.com/samlext/1.0"
       CompanyName="Example Corporation" />
</samlp:Extensions>

(This case is based on a real customer scenario; I’ve changed the XML to simplify it and to respect that customer’s confidentiality.)

In 11.1.2.3 this is possible using OIFMessageProcessingPlugin. Note that only one plugin is allowed in your OAM environment, but since the plugin is passed information on each message (e.g. name of the partner it is for, whether it is incoming or outgoing, etc), you can use conditional logic in your plugin to do different things for different messages.

This tutorial assumes you have set up OAM Federation loopback test (LoopbackIDP/LoopbackSP) per the previous post. This enables us to initially test the plugin without requiring the third party server expecting the custom elements to be available. (Of course, once you believe you have it working without the third party server, you’d want to test it with them.)

DISCLAIMER: This sample code is just a start for your own development process, it is not production quality. This is a sample only, not officially supported by Oracle, use at your own risk.

Build the example plugin

We need our Java code for our plugin. Create a directory anywhere, let us refer to it as $PLUGINDEV. Then create the directory tree $PLUGINDEV/src/oracle/ateam/msgprocplugin and in that directory place the file SampleMsgProcPlugin.java with the following content:

package oracle.ateam.msgprocplugin;

import java.io.*;
import java.util.*;
import javax.xml.parsers.*;
import oracle.security.am.plugin.*;
import oracle.security.fed.plugins.fed.msgprocessing.*;
import org.w3c.dom.*;
import org.w3c.dom.ls.*;
import org.xml.sax.*;
import static java.lang.System.err;

public class SampleMsgProcPlugin extends OIFMessageProcessingPlugin {

        private boolean monitoringStatus;

        public ExecutionStatus process(MessageContext messageCtx) throws MessageProcessingException {
                try {
                        String msg = "";
                        msg += "************************************\n";
                        msg += "* SAMPLE MESSAGE PROCESSING PLUGIN *\n";
                        msg += "************************************\n";
                        msg += "Partner Name: " + messageCtx.getPartnerName() + "\n";
                        msg += "Message Type: " + messageCtx.getMessageType() + "\n";
                        msg += "Message Version: " + messageCtx.getMessageVersion() + "\n";
                        msg += "User DN: " + messageCtx.getUserDN() + "\n";
                        msg += "User ID: " + messageCtx.getUserID() + "\n";
                        msg += "User ID Store: " + messageCtx.getUserIDStore() + "\n";

                        // Determine if this message meets our criteria for modification
                        boolean matches =
                                "LoopbackIDP".equals("" + messageCtx.getPartnerName()) &&
                                "SSO_AUTHN_REQUEST_OUTGOING".equals("" + messageCtx.getMessageType()) &&
                                "SAML2.0".equals("" + messageCtx.getMessageVersion());

                        if (!matches)
                                msg += "@@@@@@ CRITERIA NOT MET - SKIPPING THIS MESSAGE @@@@@@\n";
                        else {
                                msg += "@@@@@@ CRITERIA MET - TRANSFORMING THIS MESSAGE @@@@@@\n";
                                Element root = parseXML(messageCtx.getMessage());
                                String pretty = unparseXML(root);

                                msg += "---------- ORIGINAL XML -----------------\n";
                                msg += "\n" + pretty + "\n";

                                // Now to modify the XML message
                                Element ext = getExtensionsXML();
                                root.appendChild(root.getOwnerDocument().importNode(ext,true));

                                // DOM tree modified - unparse the DOM back into string
                                messageCtx.setModifiedMessage(unparseXML(root));

                                msg += "---------- MODIFIED XML -----------------\n";
                                msg += "\n" + messageCtx.getModifiedMessage() + "\n";
                        }

                        msg += "=================ENDS===================\n";
                        err.println(msg);
                        return ExecutionStatus.SUCCESS;
                } catch (Exception e) {
                        e.printStackTrace();
                        throw handle(e);
                }
        }

        @Override
        public String getDescription(){
                return "Sample Message Processing Plugin";
        }

        @Override
        public Map<String, MonitoringData> getMonitoringData(){
                return null;
        }

        @Override
        public boolean getMonitoringStatus(){
                return monitoringStatus;
        }

        @Override
        public String getPluginName(){
                return "SampleMsgProcPlugin";
        }

        @Override
        public int getRevision() {
                return 123;
        }

        @Override
        public void setMonitoringStatus(boolean status){
                this.monitoringStatus = status;
        }

        private RuntimeException handle(Exception e) {
                return e instanceof RuntimeException ? (RuntimeException)e : new RuntimeException(e);
        }

        private DocumentBuilderFactory createDBF() {
                try {
                        Class<?> c = Class.forName("com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl",true,ClassLoader.getSystemClassLoader());
                        return (DocumentBuilderFactory) c.newInstance();
                } catch (Exception e) {
                        throw handle(e);
                }
        }
        
        private Element parseXML(String xml) {
                try {
                        DocumentBuilderFactory dbf = createDBF();
                        dbf.setNamespaceAware(true);
                        DocumentBuilder db = dbf.newDocumentBuilder();
                        StringReader sr = new StringReader(xml);
                        InputSource is = new InputSource(sr);
                        Document doc = db.parse(is);
                        return doc.getDocumentElement();
                } catch (Exception e) {
                        throw handle(e);
                }
        }

        private DOMImplementationSource getDOMImpl() {
                try {
                        Class<?> c = Class.forName("com.sun.org.apache.xerces.internal.dom.DOMXSImplementationSourceImpl",true,ClassLoader.getSystemClassLoader());
                        return (DOMImplementationSource) c.newInstance();
                } catch (Exception e) {
                        throw handle(e);
                }
        }

        private String unparseXML(Node node) {
                try {
                        Document doc = node.getOwnerDocument();
                        DOMImplementationSource reg = getDOMImpl();
                        DOMImplementationLS ls = (DOMImplementationLS) reg.getDOMImplementation("LS");
                        LSSerializer w = ls.createLSSerializer();
                        w.getDomConfig().setParameter("format-pretty-print", Boolean.TRUE);
                        w.getDomConfig().setParameter("xml-declaration", Boolean.TRUE);
                        String ppxml = w.writeToString(doc);
                        return ppxml.replace("<?xml version=\"1.0\" encoding=\"UTF-16\"?>","<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
                } catch (Exception e) {
                        throw handle(e);
                }
        }

        private Element getExtensionsXML() {
                String extensionsXML = "";
                extensionsXML += "<samlp:Extensions xmlns:samlp=\"urn:oasis:names:tc:SAML:2.0:protocol\">\n";
                extensionsXML += "        <CompanyInfo xmlns=\"http://example.com/samlext/1.0\"\n";
                extensionsXML += "             CompanyName=\"Example Corporation\" />n";
                extensionsXML += "</samlp:Extensions>\n";
                return parseXML(extensionsXML);
        }

        private Element getChildElem(Node node,String nsuri, String name) {
                try {
                        NodeList kids = node.getChildNodes();
                        for (int i = 0; i < kids.getLength(); i++) {
                                Node k = kids.item(i);
                                if (k.getNodeType() != org.w3c.dom.Node.ELEMENT_NODE) continue;
                                if (!Objects.equals(k.getNamespaceURI(),nsuri)) continue;
                                if (!Objects.equals(k.getLocalName(),name)) continue;
                                return (Element)k;
                        }
                        return null;
                } catch (Exception e) {
                        throw handle(e);
                }
        }
}

Question: Why do I get the DOM factory objects directly from the System Class Loader using Class.forName?

Answer: I tried doing it the normal way, but OAM overrides the standard JDK XML classes with some Oracle-specific ones that don’t implement DOM 3 Load and Save. So by doing it this way I make sure I get an XML implementation that has the features I need.

Next we need to create the XML plugin manifest $PLUGINDEV/SampleMsgProcPlugin.xml:

<?xml version="1.0"?>
<Plugin type="Message Processing">
  <author>Oracle A-Team</author>
  <email>donotreply@oracle.com</email>
  <creationDate>2015-04-16 12:53:37</creationDate>
  <description>Sample Message Processing Plugin</description>
  <configuration>
  </configuration>
</Plugin>

Here we could, if we so wished, define some configuration settings for our plugin, that could then be modified using the OAM Console. However, in this simple example, we have not done that.

Next we need to create $PLUGINDEV/MANIFEST.MF file:

Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: SampleMsgProcPlugin
Bundle-SymbolicName: SampleMsgProcPlugin
Bundle-Version: 1
Bundle-Activator: oracle.ateam.msgprocplugin.SampleMsgProcPlugin
Import-Package: javax.xml.parsers,oracle.security.am.plugin,oracle.security.fed.plugins.fed.msgprocessing,org.osgi.framework;version="1.3.0",org.w3c.dom,org.w3c.dom.ls,org.xml.sax
Bundle-RequiredExecutionEnvironment: JavaSE-1.6

This is the OSGi bundle metadata. Notably, it lists the Java packages our plugin requires. (Note that Import-Package is all on one-line.)

Next we need to create $PLUGINDEV/compile.sh file:

#!/bin/bash
DOMAIN_HOME=/idmtop/config/domains/IAMAccessDomain
SERVER_NAME=wls_oam1

JARS="$(find $DOMAIN_HOME/servers/$SERVER_NAME/tmp/_WL_user/oam_server_11.1.2.0.0/ -name fed.jar -o -name oam-plugin.jar -o -name felix.jar | tr '\n' ':' | sed -e 's/:$//')"
SRCS="$(find src -name '*.java')"
rm -rf build
mkdir build
javac -d build -classpath $JARS $SRCS
cp SampleMsgProcPlugin.xml build
mkdir build/META-INF
cp MANIFEST.MF build/META-INF
cd build
jar cvmf META-INF/MANIFEST.MF ../SampleMsgProcPlugin.jar *

This shell script compiles the plugin for us. (Of course, one should use something like ANT or Maven instead, but for our simple example a shell script will do.) Note the path DOMAIN_HOME and the SERVER_NAME may need to be changed for your environment. Also note that JARS= is supposed to all be on one line (in case your web browser is wrapping it).

Finally we run compile.sh to create SampleMsgProcPlugin.jar.

Deploy the example plugin

Login to OAM Console

Go to “Application Security” tab

In “Plug-ins” section select “Authentication Plug-ins”:

Note: Even though the label says “Authentication Plug-ins”, the same screen works for non-authentication types of plugins, such as the message processing plugin in this case.

Click “Import Plugin”:

Upload “SampleMsgProcPlugin.jar” you built in earlier step and click “Import”:

Refresh the table and search for the new plugin:

Click “Distribute Selected”, then click Refresh icon to see status has changed to “Distributed”:

Now click “Activate Selected”, then click Refresh icon to see status has changed to “Activated”:

Enabling message processing plugin

The plugin has now been installed. Now we need to tell OAM Federation to use it. Edit the $DOMAIN_HOME/config/fmwconfig/oam-config.xml file. Look for the “fedserverconfig” section:

In that section, look for a setting called “messageprocessingeplugin”:

Change its value to the name of your plugin:

Also, in the same section, look for a setting called “messageprocessingenabled”:

Change that from “false” to “true”.

Finally, near the top of the file, look for a version number:

Increment that number by 1, and save. (It doesn’t matter by how much you increment it, so long as the new version number is higher than the old one.)

Now check the oam-config.ref file in the same directory:

When the version number in that file has increased to the new number in the oam-config.xml, you know the new number has been loaded.

Testing the new plugin

Go to the SP Test Page (http://OAMHOST:OAMPORT/oamfed/user/testspsso). This assumes you have enabled it per my previous post. Test using LoopbackIDP. As you test, watch SAML messages using e.g. SAML Tracer plugin in Firefox [https://addons.mozilla.org/en-us/firefox/addon/saml-tracer/]. You should see the custom XML extension in the SAML AuthnRequest in SAML Tracer:

Also note the custom plugin writes to the wls_oam1 console log every time it runs:

You would probably not want to do this in Production, but it is helpful in development. And you’d want to make it log through java.util.logging not System.err.println. Remember this sample code is just a start for your own development process, it is not meant to be production quality.

OAM Federation 11.1.2.3: Performing a loopback test with WS-Federation

Next: Implementing OAuth 2 with Oracle Access Manager OAuth Services (Part I)
Previous: OAM Federation 11.1.2.3: Example Message Processing Plugin
$
0
0

In a previous post I gave steps for performing a loopback test with SAML. This is where we configure OAM Federation to talk to itself, to act as both IdP and SP. This is useful in development and test environments to confirm OAM Federation is working without requiring an external server to talk to at the other end. So in this post, I want to do the same for WS-Federation (WS-Fed).

SAML vs WS-Fed

Support for WS-Federation (WS-Fed), and specifically the WS-Fed Passive Requestor Profile (WS-Fed PRP), was introduced in OAM Federation 11.1.2.3. Support for WS-Fed PRP in OAM 11.1.2.3 is similar to the support for WS-Federation in the 11.1.1.x Oracle Identity Federation (OIF) standalone product. OAM Federation 11.1.2.3 does not support the WS-Fed Active Requestor Profile.

WS-Fed is a competing federation protocol to SAML: the capabilities each provides are largely similar, but the underlying protocols are different and each uses distinct terminology. Most vendors, including Oracle, have focused on SAML for identity federation; WS-Fed has seen limited adoption outside of Microsoft-centric environments. Given that, if you have a choice, I would strongly recommend using SAML over WS-Fed.

There are two primary cases in which the need for WS-Fed may be encountered:

  • Active Directory Federation Services (ADFS): since this supports both SAML and WS-Fed, either protocol could be used for integration with OAM Federation. But the SAML-based integration should be preferred, since that is what most customers with this use case successfully use.
  • ASP.NET and WCF applications: the Windows Identity Federation (WIF) component shipped with .NET 4.5 and later supports WS-Fed protecting ASP.NET and WCF applications simply through XML configuration changes (i.e. no code required.) By contrast, while it does include some .Net classes for validating SAML tokens, it does not contain a complete implementation of the SAML protocol, so ASP.NET/WCF applications cannot be federated with SAML unless you either write some custom code, or use third party components. Due to this, when you have existing ASP.NET/WCF apps, migrating them from WS-Fed to SAML can be time-consuming.

Given this situation, the main use case for using WS-Fed with OAM Federation is ASP.NET or WCF applications.

Configuring OAM for the WS-Fed loopback test

We assume you have OAM 11.1.2.3 up and running, and that you have enabled the Federation Service in the OAM console. Also, note that if you did the SAML Loopback test from my previous blog post the SAML and WS-Fed Loopback test configurations cannot co-exist at the same time. This is because OAM Federation only supports a single protocol per a provider URL – either SAML or WS-Fed. In practice, this should not be an issue, since if a given provider URL supports multiple protocols, it makes sense for OAM to use one of those protocols only to communicate with it.

In order to configure a WS-Federation partner, you need to use WLST commands. The OAM Console web application cannot create or edit WS-Federation partners, although it can be used to delete them.

We need to export the certificate stscertalias from the $DOMAIN_HOME/config/fmwconfig/.oamkeystore
Use this command:

$JAVA_HOME/bin/keytool -exportcert -keystore $DOMAIN_HOME/config/fmwconfig/.oamkeystore -storetype JCEKS -alias stscertalias -file /tmp/stscertalias.cer -v

When it asks you for the password, you can just press ENTER and ignore the WARNING. (You don’t actually need to know the password to export the certificate.)

Next we run the following commands using $OAM_ORACLE_HOME/common/bin/wlst.sh:

connect("weblogic","welcome1","t3://ADMINSERVERHOST:ADMINSERVERPORT")
domainRuntime()
configureTestSPEngine("true")
deleteFederationPartner(partnerName="LoopbackIDP", partnerType="idp")
deleteFederationPartner(partnerName="LoopbackSP", partnerType="sp")
addWSFed11IdPFederationPartner(partnerName="LoopbackIDP", providerID="http://OAMHOST:OAMPORT/oam/fed",ssoURL="http://OAMHOST:OAMPORT/oamfed/idp/wsfed11")
addWSFed11SPFederationPartner(partnerName="LoopbackSP", realm="http://OAMHOST:OAMPORT/oam/fed", ssoURL="http://OAMHOST:OAMPORT/oamfed/sp/wsfed11")
setFederationPartnerSigningCert(partnerName="LoopbackIDP",partnerType="idp",certFile="/tmp/stscertalias.cer")

Of course, you will replace ADMINSERVERHOST, ADMINSERVERPORT, OAMHOST and OAMPORT with appropriate values for your environment.

Note that we are calling configureTestSPEngine() to run enable the OAM Federation test page – we will use that in our testing below. Note also that we are calling deleteFederationPartner() to delete the federation partners first. The first time you run this script, these two commands will print an error. However, by including them, we make it possible to run the script multiple times, and have it delete any existing provider by that name before creating the new one.

Performing the loopback test

Open a new private browsing window, and go to the URL http://OAMHOST:OAMPORT/oamfed/user/testspsso, you should see the following displayed:
WSFedBlogPost-001
(Note: if you find the screenshots hard to read, click on them to load higher resolution versions)

Selecting “LoopbackIDP”, and clicking on “Start SSO”, we should get the OAM login page:
WSFedBlogPost-002
I try logging in as “weblogic”, and then I get this error:
WSFedBlogPost-003
What went wrong here? Out-of-the-box, the “weblogic” user included in the Embedded WebLogic LDAP does not have an email attribute, which is what we use by default as our NameID format. To fix this, I can set an email attribute on that user. Go to WLS console > Security Realm > myrealm > Users and Groups > Users > weblogic > Attributes. Find the “mail” attribute (it should be on the second page), click on its Value table cell, and enter an email address (e.g. weblogic@example.com):
WSFedBlogPost-004
Then press ENTER to save. Now if we try the test again using a new private browsing window, it works:
WSFedBlogPost-005
Note: if you don’t use a new private browsing window, and try the test again with the original window, you will get the same error again. This is because OAM Federation does not pick up the change in email address until the user logs out and logs in again.

Implementing OAuth 2 with Oracle Access Manager OAuth Services (Part I)

Next: Implementing OAuth 2 with Oracle Access Manager OAuth Services (Part II)
Previous: OAM Federation 11.1.2.3: Performing a loopback test with WS-Federation
$
0
0

Introduction

This post will explain the basics of OAuth 2.0 and how it can be used to protect resources by implementing some of the most common OAuth use cases.

OAM provides out of the box OAuth Services, which allows a Client Application to access protected resources that belong to an end-user (that is, the Resource Owner).

Before going further in this post, check out the OAuth2 specification, to understand the basic OAuth concepts, as it won’t be covered in this post.

This post will be divided into 5 parts:

Part I – explains the proposed architecture and how to enable and configure OAM OAuth Services.

Part II – describes a Business to Business use-case (2-legged flow);

Part III  – explains the Customer to Business use-case (3-legged flow), when the client application is running in the application server;

Part IV – describes the Customer to Business use-case (3-legged flow), when the client application runs on the browser, embedded as Javascript code;

Part V  – discuss Access Token and Refresh Token usage/strategy and provides the source code for the use-case examples.

Architecture

The picture below represents an overview of the different components and the interaction between them.

Architecture

 

  • Client WebApplication: The applications play the role of OAuth Clients. The applications will request access to resources owned by the end user.
  • ResourceServer: Those are RESTful webservices that represent the protected resources owned by the end user. They require a valid OAuth token in order to serve information back to the ClientWebApp.
  • OAM/OAuth Server: Responsible for authenticating the end user and for issuing and validating OAuth Tokens.

Configuration

The configuration takes place in the OAM Mobile and Social component, in the OAuth Services page.

You need to have access to the OAM Console at http://oam_admin_server:port/oamconsole to perform the required configurations.

Before proceeding, make sure you have enabled OAuth Services by following the steps described here.

Before jumping into the OAuth flow and code examples, we need to register Clients and Resources Serveres with OAM.

For the B2B use-case, presented in part II, we will need to register a ‘Business’ Resource Server and a ‘BusinessClient’ Client.

The Business Client will request access to some resources from the Business Resource Server, passing an Access Token, obtained from OAM’s OAuth Server.

For the C2B use-cases, we will register one Resource Server: ‘Customer Resource Server’. It will be used for both C2B use-cases (app running in the application server and app running as embedded Javascript code).

We will also register the following clients: ‘Customer Client’ (for the C2B use-case where the app runs in the application server) and the ‘Browser Client’ (for the C2B use-case where the app runs as embedded Javascript code).

In all cases, the Resource Servers will need to validate the Access Token, before granting access to the protected resources.

To achieve this, there are two different approaches:

1 – Use a ‘special’ client, we’re calling it the ‘Service Token Validator’, which is just another OAuth client, with no grant types provileges but it is configured to retrieve additional token attributes (useful for token validation). This approach is simple and requires almost no coding since it only required a REST call to the OAuth Server, passing the Access Token. This is the simplest choice but won’t be really useful in real world application as it does not scale and performs well;

2 – Export the OAuth Server signing key and implementing a piece of code in the Resource Server that validates the Access Token signature and claims. This approach is a bit more complicated as it involves some 3rd party library, different keys, claims, etc.

Both approaches are explained in part V of this post series, and considerations are discussed in part V regarding the cons/pros of one over another.

Creating a Custom Resource Server

A Resource Server represents a 3rd party Service or Application that your clients are entitled to have access to.

The use-cases proposed here will use ‘business’ and ‘clients’ services, so two Resource Servers will be created in OAM: ‘Business Service‘ and ‘Client Service’.

The Business Service will be used in the B2B use-case and the Client Service will be used in the C2B use-cases.

To create the Resource Servers, follow these steps:

1. Log in to OAM Console, in the Launch Pad page, open the OAuth Service page.

img1

 

2. Select the Default Domain.

img2

 

3. Open the Resource Servers tab.

img3

 

4. On the Custom Resource Servers table, click ‘create’ and create two Resource Servers according to the information below.

img4

 

 

Business Resource Server

Name: Business

Authorization & Consent Service Plug-in: CoherenceAuthzUserConsentPlugin

Scope Namespace Prefix: Business

Scopes: Info

Decription: Reads Business Information

 

Your Business Resource Server should look like this:

img5

 

Customer Resource Server

Name: Customer

Authorization & Consent Service Plug-in: CoherenceAuthzUserConsentPlugin

Scope Namespace Prefix: Customer

Scopes: Info

Description: Reads Customer Information

 

Your Customer Resource Server should look like this:

img6

 

 

OAuth Client Registration

In OAuth2, clients are “applications making protected resource requests on behalf of the resource owner and with its authorization.”

The Services, or Applications, that play the roles of Resource Servers in our use cases, will validate the OAuth token received from the clients when those clients request access to their protected resources.

To do so, our Services will need to be registered as ‘special’ clients with OAM, with the only purpose of validating OAuth tokens. More on that later.

Four OAuth clients will be registered, one for the Business Use Case (B2B), one for the C2B Use Case – server side application, one for the C2B Use Case – application embedded as Javascript code, and one additional client for our Resource Server applications to validate the Access Tokens.

 

Access the OAM Console,  and execute the following steps:

1. On the Launch Pad page, in the Mobile and Social section, click on OAuth Service link. The OAuth Identity Domains tab appears.

2. Click on  the Defaul Domain, and open the OAuth Clients tab.

img7

3. Click on the Create button and enter the appropriate data to create the clients (execute this step 4 times for each client with the data below).

 

Business Client

The Business Client represents the business client application in the B2B use case.

This application will make calls to the Resource Server represented by a RESTful web service that will provide business information based on the client ID.

Set the following properties for the Business Client:

Client ID: businessClient

Client Secret: 3WFLudTFyBk

Bypass User Consent: checked

Allowed Scopes: Business.Info

Grant Types: Client Credentials

 

Your Business Client should look like this:

img8

 

Customer Client

The Customer Client represents the customer client application, in the C2B use case, where the application runs on the server side.

This application will make calls to the Resource Server represented by a RESTful web service that will provide information based on the end user authenticated with OAM.

Set the following properties for the Customer Client:

Client ID: customerClient

Client Secret: zRpJbl73iE8X

HTTP Redirect URIs: https://oxygen.mycompany.com:7502/ClientWebApp/CustomerClient

(This is the URI of the client application that will receive the Authorization Token, after the user successfully authenticates. See the provided source code for more details).

Allowed Scopes: Customer.Info, UserProfile.me

Grant Types: Authorization Code

 

Your Customer Client should look like this:

img9

 

Browser Client

The Browser Client represents the customer client application, in the C2B use case, where the application runs on the browser itself.

This application will make calls to the Resource Server represented by a RESTful web service that will provide information based on the end user authenticated with OAM.

Client ID: browserClient

Client Secret: g8aGglZDrPDl7e

HTTP Redirect URIs: https://oxygen.mycompany.com:7502/ClientWebApp/index.html

(This is the URI of your client application that will receive the Authorization Token, after the user successfully authenticates).

Allowed Scopes: Customer.Info, UserProfile.me

Grant Types: Authorization Code

 

Your Browser Client should look like this:

img10

 

 

Service Token Validator

The Service Token Validator is a ‘special’ client; it actually runs on the Resource Server side, and will only be used by the Resource Server to validate the incoming OAuth Access Tokens.

Client ID: ServiceTokenValidator

Allow Token Attributes Retrieval: Checked.

(This will allow our client to obtain detailed information about the Access Token along with its validation status.)

Client Secret: A3nqKocV6I0GJB

No other information is required for this client.

 

Your Service Token Validator Client should look like this:

 

img11

 

 

That’s it for now, in the following post we will cover the Business to Business Use case.

Implementing OAuth 2 with Oracle Access Manager OAuth Services (Part II)

Next: Implementing OAuth 2 with Oracle Access Manager OAuth Services (Part III)
Previous: Implementing OAuth 2 with Oracle Access Manager OAuth Services (Part I)
$
0
0

Introduction

This post is part of a series of posts about OAM’s OAuth implementation.

Other posts can be found here:

Part I – explains the proposed architecture and how to enable and configure OAM OAuth Services.

Part II – describes a Business to Business use-case (2-legged flow);

Part III  – deals with the Customer to Business use-case (3-legged flow), when the client code is running in the application server;

Part IV – describes the Customer to Business use-case (3-legged flow), when the client application runs on the browser, embedded as Javascript code;

Part V  – provides the source code and additional information for the use case implementation.

The B2B (or Business to Business) use-case, usually represents an application that calls another application or service, without end user intervention.

In this example, the BusinessClient application (in OAuth spec, called a client) will make a call to a service, BusinessService (in OAuth spec, a Resource Server), and request some Business Information, passing the Access Token.

Since there is no end user intervention, the client is pre authorized to have access to the resource, making this use case one of the simplest to implement.

In this implementation, a Java Servlet will be used to simulate the BusinessClient, so that the flow can be started at will, and a Java RESTful web service will be used to represent the Resource Server.

Use Case Flow

The following picture shows the flow between the different components.

B2B Use Case - New Page

 

Steps details:

1. BusinessClient requests an OAuth Token from OAuth Server using “Client Credentials” grant type.

The BusinessClient application must be registered with OAM OAuth Server as an OAuth client and it must send its credentials in a Base64 encoded string in the Authorization Header.

The application also declares the scope for which it is requesting the token.

The call would look like this in curl:

curl -i -H “Authorization: Basic YnVzaW5lc3NDbGllbnQ6M1dGTHVkVEZ5Qms=” -H “Content-Type: application/x-www-form-urlencoded;charset=UTF-8″ –request POST https://oxygen.mycompany.com:14101/ms_oauth/oauth2/endpoints/oauthservice/tokens -d ‘grant_type=client_credentials&scope=Business.Info’

2. The OAuth Server checks the client credentials, the grant type and if it is authorized to request the scope.

Note that in Part I of this post, the BusinessClient was defined to request tokens using “Client Credentials” grant type and authorized to request “Business.Info” scopes only.

If a client tries to request tokens using a grant type or a scope it is not authorized to, it will receive an error.

 

3. The OAuth Server also checks if the user has granted permission to the client to request a token in its behalf.

In the B2B use case, there is no user intervention, this client is already allowed to request tokens without representing an end user identity. Remember that in Part I, in the BusinessClient configuration, “Bypass User Consent” is checked.

 

4. OAuth Server returns the Access Token for the BusinessClient.

The OAuth Server response for an Access Token request would look like this:

{“expires_in”:3600,”token_type”:”Bearer”,”access_token”:”eyJhbGciOiJSUzUxMiIsInR5cCI6IkpXVCIsImtpZCI6Im9yYWtleSJ9.eyJzdWIiOiJidXNpbmVzc0NsaWVudCIsImlzcyI6Ind3dy5vcmFjbGUuZXhhbXBsZS5jb20iLCJvcmFjbGUub2F1dGguc3ZjX3BfbiI6Ik9BdXRoU2VydmljZVByb2ZpbGUiLCJpYXQiOjE0MzY0NzUwODgwMDAsIm9yYWNsZS5vYXV0aC5wcm4uaWRfdHlwZSI6IkNsaWVudElEIiwiZXhwIjoxNDM2NDc4Njg4MDAwLCJvcmFjbGUub2F1dGgudGtfY29udGV4dCI6InJlc291cmNlX2FjY2Vzc190ayIsInBybiI6ImJ1c2luZXNzQ2xpZW50IiwianRpIjoiNjQwNzEwOTQtOGQyNS00Y2I3LWI5NmMtNDQxZDJmNDI2MjJkIiwib3JhY2xlLm9hdXRoLmNsaWVudF9vcmlnaW5faWQiOiJidXNpbmVzc0NsaWVudCIsIm9yYWNsZS5vYXV0aC5zY29wZSI6IkJ1c2luZXNzLkluZm8iLCJ1c2VyLnRlbmFudC5uYW1lIjoiRGVmYXVsdERvbWFpbiIsIm9yYWNsZS5vYXV0aC5pZF9kX2lkIjoiMTIzNDU2NzgtMTIzNC0xMjM0LTEyMzQtMTIzNDU2Nzg5MDEyIn0.GXcQ3sjFyxcwO85x50zRfZCXf-YEUgFerudOoRVky5a334p3GmlKl147OarZs-h0uGl5okrp0Ivfx7ed2Y7jR0nbTTye6TxiSgCyHrJXjp5_blwRH6hj05KI6RxWdzJJqeC95Kgfh-m2FOqbffQOC1XhHvoWQ8KkG9ub5ZgmhPo”}

This token is not associated with a end-user, it contains the OAuth client application information only.

We will see the difference between this kind of token and the token from a 3-legged OAuth flow.

When decoded, the following revelant information can be extracted from the token:

{
“sub”: “businessClient”,
“iss”: “www.oracle.example.com”,
“oracle.oauth.svc_p_n”: “OAuthServiceProfile”,
“iat”: 1436475088000,
“oracle.oauth.prn.id_type”: “ClientID”,
“exp”: 1436478688000,
“oracle.oauth.tk_context”: “resource_access_tk”,
“prn”: “businessClient”,
“jti”: “64071094-8d25-4cb7-b96c-441d2f42622d”,
“oracle.oauth.client_origin_id”: “businessClient”,
“oracle.oauth.scope”: “Business.Info”,
“user.tenant.name”: “DefaultDomain”,
“oracle.oauth.id_d_id”: “12345678-1234-1234-1234-123456789012″
}

 

5. Now, with the Access Token, the BusinessClient makes a remote call to the ResourceServer passing the token in the POST parameters.

 

6. The ResourceServer receives the token and makes a call to the OAuth Server to validate the token.

The OAuth server will assert if the token has not expired, has not been tampered with, if it has not been revoked and if the scope is valid.

To make this call, the Resource Server must also be registered as an OAuth client, the Service Token Validator, explained in Part I of this post.

Note below that this client has no scopes or is allowed any grants, it is only used to validate tokens.

The validation can be a simple one or can be a token instrospection, which retrives additional attributes.

Validation calls would look like this:

Simple Validation request:

curl -i -H ‘Authorization: Basic YnVzaW5lc3NDbGllbnQ6M1dGTHVkVEZ5Qms=’ –request POST http://oxygen.mycompany.com:14100/ms_oauth/oauth2/endpoints/oauthservice/tokens -d ‘grant_type=oracle-idm%3A%2Foauth%2Fgrant-type%2Fresource-access-token%2Fjwt&oracle_token_action=validate&scope=UserProfile.me&assertion=eyJhbGciOiJSUzUxMiIsInR5cCI6IkpXVCIsImtpZCI6Im9yYWtleSJ9.eyJzdWIiOiJidXNpbmVzc0NsaWVudCIsImlzcyI6Ind3dy5vcmFjbGUuZXhhbXBsZS5jb20iLCJvcmFjbGUub2F1dGguc3ZjX3BfbiI6Ik9BdXRoU2VydmljZVByb2ZpbGUiLCJpYXQiOjE0MzA4MjczMzAwMDAsIm9yYWNsZS5vYXV0aC5wcm4uaWRfdHlwZSI6IkNsaWVudElEIiwiZXhwIjoxNDMwODMwOTMwMDAwLCJvcmFjbGUub2F1dGgudGtfY29udGV4dCI6InJlc291cmNlX2FjY2Vzc190ayIsInBybiI6ImJ1c2luZXNzQ2xpZW50IiwianRpIjoiNzBiZTRjOTItZWNmNi00YWM0LWEzOGEtZjUyMzUwMzUzNDJjIiwib3JhY2xlLm9hdXRoLmNsaWVudF9vcmlnaW5faWQiOiJidXNpbmVzc0NsaWVudCIsIm9yYWNsZS5vYXV0aC5zY29wZSI6IlVzZXJQcm9maWxlLm1lIiwidXNlci50ZW5hbnQubmFtZSI6IkRlZmF1bHREb21haW4iLCJvcmFjbGUub2F1dGguaWRfZF9pZCI6IjEyMzQ1Njc4LTEyMzQtMTIzNC0xMjM0LTEyMzQ1Njc4OTAxMiJ9.omYuR3KOsg5QbzYSq98aqtBUb37mpEeSKu-8U5-RVfZ16XceFcDRiDZ8upJcVoRyolpl52RFqjBdIDKRJQK6C21ZBkVhHKUvSyrJCD1AVATihq8Xm2mr0zZuRg6iqbalZEXfuIKd8hU4Q863aMwmo-W9j2Ep63ebTeXpHPkkWcI’

Token Introspection request:

curl -i -H ‘Authorization: Basic YnVzaW5lc3NDbGllbnQ6M1dGTHVkVEZ5Qms=’ –request POST http://oxygen.mycompany.com:14100/ms_oauth/oauth2/endpoints/oauthservice/tokens -d ‘grant_type=oracle-idm%3A%2Foauth%2Fgrant-type%2Fresource-access-token%2Fjwt&oracle_token_action=validate&scope=UserProfile.me&oracle_token_attrs_retrieval=iss%20aud%20exp%20prn%20jti%20exp%20iat%20oracle.oauth.scope%20oracle.oauth.client_origin_id%20oracle.oauth.user_origin_id%20oracle.oauth.user_origin_id_type%20oracle.oauth.tk_context%20oracle.oauth.id_d_id%20oracle.oauth.svc_p_n&assertion=eyJhbGciOiJSUzUxMiIsInR5cCI6IkpXVCIsImtpZCI6Im9yYWtleSJ9.eyJzdWIiOiJidXNpbmVzc0NsaWVudCIsImlzcyI6Ind3dy5vcmFjbGUuZXhhbXBsZS5jb20iLCJvcmFjbGUub2F1dGguc3ZjX3BfbiI6Ik9BdXRoU2VydmljZVByb2ZpbGUiLCJpYXQiOjE0MzA4MjczMzAwMDAsIm9yYWNsZS5vYXV0aC5wcm4uaWRfdHlwZSI6IkNsaWVudElEIiwiZXhwIjoxNDMwODMwOTMwMDAwLCJvcmFjbGUub2F1dGgudGtfY29udGV4dCI6InJlc291cmNlX2FjY2Vzc190ayIsInBybiI6ImJ1c2luZXNzQ2xpZW50IiwianRpIjoiNzBiZTRjOTItZWNmNi00YWM0LWEzOGEtZjUyMzUwMzUzNDJjIiwib3JhY2xlLm9hdXRoLmNsaWVudF9vcmlnaW5faWQiOiJidXNpbmVzc0NsaWVudCIsIm9yYWNsZS5vYXV0aC5zY29wZSI6IlVzZXJQcm9maWxlLm1lIiwidXNlci50ZW5hbnQubmFtZSI6IkRlZmF1bHREb21haW4iLCJvcmFjbGUub2F1dGguaWRfZF9pZCI6IjEyMzQ1Njc4LTEyMzQtMTIzNC0xMjM0LTEyMzQ1Njc4OTAxMiJ9.omYuR3KOsg5QbzYSq98aqtBUb37mpEeSKu-8U5-RVfZ16XceFcDRiDZ8upJcVoRyolpl52RFqjBdIDKRJQK6C21ZBkVhHKUvSyrJCD1AVATihq8Xm2mr0zZuRg6iqbalZEXfuIKd8hU4Q863aMwmo-W9j2Ep63ebTeXpHPkkWcI’

 

7. The OAuth server responds with the results of the token validation, that would look like this:

The simple validation response:

{“successful”:true}

The Token introspection response:

{“successful”:true,”oracle_token_attrs_retrieval”:{“oracle.oauth.tk_context”:”resource_access_tk”,”exp”:1430830930000,”iss”:”www.oracle.example.com”,”prn”:”businessClient”,”oracle.oauth.client_origin_id”:”businessClient”,”oracle.oauth.scope”:”UserProfile.me”,”jti”:”70be4c92-ecf6-4ac4-a38a-f5235035342c”,”oracle.oauth.svc_p_n”:”OAuthServiceProfile”,”iat”:1430827330000,”oracle.oauth.id_d_id”:”12345678-1234-1234-1234-123456789012″}}

Note that the token for a B2B use case represents just the identity of the OAuth client (“prn”:”businessClient” and “oracle.oauth.client_origin.id”:”businessClient”), it does not contain any reference to an end user because the BusinessClient is pre-authorized and haven’t gone through a user authentication or user consent.

 

8. The resource server is responsible for the implementation of the authorization logic itself, therefore it is up to the ResourceServer to make the decision if the scope for which the token was issued is valid or any other reason it might consider to give access for the requesting application.

If all checks are satisfied, the ResourceServer returns the requested data back to the client.

 

B2B Use Case Implementation

To implement the B2B use case, a standard Java Servlet will be used, BusinessClient.java, so that the use case can be triggered at will.

In a real world situation, it could well be any piece of code running on the server in a scheduled timer, without user intervention.

This servlet, will obtain an Access Token from the OAuth Server, using the Client Credentials grant type, and will pass the Access Token to the Resource Server, when making the call to the Business RESTful endpoint.

The Resource Service will be implemented in a annotated plain Java class using the Jersey framework to expose the Business Service as a RESTful webservice.

The Resource Server also implements a Servlet Filter, that intercepts all incoming requests to validate the incoming Access Token before giving access to the REST Endpoint.

The RESTful WS implementation, BusinessService.java is completely independent from the OAuth implementation.

In a real world case, it might be a good practice to implement Filters, or any other way to intercept the incoming request, and validate the token or other decisions, like scope, before passing the request along to the endpoint.

The complete source code will be provided in the Part VI of this post.

The relevant classes for this use case are:

  • BusinessClient.java
  • OAuthTokenValidationFilter.java
  • OAuthTokenValidator.java
  • BusinessService.java

In the next post we will cover the Customer to Business Use case, when the client application runs on the application server.

Implementing OAuth 2 with Oracle Access Manager OAuth Services (Part III)

Next: Implementing OAuth 2 with Oracle Access Manager OAuth Services (Part IV)
Previous: Implementing OAuth 2 with Oracle Access Manager OAuth Services (Part II)
$
0
0

Introduction

This post is part of a serie of posts about OAM’s OAuth implementation.

Other posts can be found here:

Part I – explains the proposed architecture and how to enable and configure OAM OAuth Services.

Part II – describes a Business to Business use-case (2-legged flow);

Part III  – deals with the Customer to Business use-case (3-legged flow), when the client code is running in the application server;

Part IV – describes the Customer to Business use-case (3-legged flow), when the client application runs on the browser, embedded as Javascript code;

Part V  – provides the source code and additional information for the use case implementation.

This post will cover the C2B (Customer to Business) Use Case, when the Client Application is running on the Server.

In this case, an end user accesses an Application, which needs to fetch data from a Resource Server in behalf of the end user, but without the end user providing his credentials to the Application.

The user has to provide his consent for the client application to access his resources in the Resource Server.

In this use case, all the code resides in the server and it is not visible to the end user.

Use Case Flow

The following picture shows the flow between the different components

C2B1

 

1. A User Agent, usually a browser, accesses the Application, starting the OAuth flow.

2. The Application detects that the user have not presented an Authorization Code, then it redirects the user to the OAM/OAuth authorization URL.

The redirect is a standard HTTP browser redirect that looks like this:

https://oxygen.mycompany.com:14101/ms_oauth/oauth2/endpoints/oauthservice/authorize?client_id=customerClient&response_type=code&redirect_uri=https://oxygen.mycompany.com:7502/ClientWebApp/CustomerClient&scope=Customer.Info%20UserProfile.me

Some things to note here:

The Application identifies itself with its ID, client_id=customerClient;

The expected response type is the authorization code, response_type=code;

The redirect URI, to where the OAuth server will redirect the request with the authorization code as URL parameter after the user successfully logs in;
And lastly the requested Scope, Customer.Info and UserProfile.me

In this step the OAuth server checks if the requesting client is correctly registered, if it has the correct grant type enabled, in this case Authorization Code, if the redirect_uri is matches the one defined in the client configuration and if it is requesting a scope allowed for this client.

If the conditions above are not met, the OAuth server send and error back and does not proceed to the user authentication.

3. OAuth Server redirects the user to OAM Login Page.

4. User logs in with his credentials.

5. Since the user has started an OAuth flow in step 1, the OAuth server needs the user consent to provide a token to this application which will be used to access the user resource on the Resource Server.

6. OAuth server redirects the user to the consent page so the user can consent or reject the Application access to his resources.

The consent page looks like this:

C2B2

7. The user grants access to the CustomerClient Application

8. The OAuth server returns the Authorization Code the the URI defined in the redirect_uri as an URL parameter.

The response looks like this:

https://oxygen.mycompany.com:7502/ClientWebApp/CustomerClient?code=eyJhbGciOiJSUzUxMiIsInR5cCI6IkpXVCIsImtpZCI6Im9yYWtleSJ9.eyJvcmFjbGUub2F1dGgucmVkaXJlY3QtdXJpIjoiaHR0cHM6Ly9veHlnZW4ubXljb21wYW55LmNvbTo3NTAyL0NsaWVudFdlYkFwcC9DdXN0b21lclNlcnZsZXQiLCJvcmFjbGUub2F1dGgudXNlcl9vcmlnaW5faWRfdHlwZSI6IkxEQVBfVUlEIiwib3JhY2xlLm9hdXRoLnVzZXJfb3JpZ2luX2lkIjoicGF1bG8iLCJpc3MiOiJ3d3cub3JhY2xlLmV4YW1wbGUuY29tIiwib3JhY2xlLm9hdXRoLnN2Y19wX24iOiJPQXV0aFNlcnZpY2VQcm9maWxlIiwiaWF0IjoxNDMxMTAyNjIyMDAwLCJvcmFjbGUub2F1dGgudGtfY29udGV4dCI6ImF6YyIsImV4cCI6MTQzMTEwMzUyMjAwMCwicHJuIjpudWxsLCJqdGkiOiI2OTkwNDRlZi0zM2IwLTRhNDUtYjI4MS1jYTNjMTc2NzhkNTciLCJvcmFjbGUub2F1dGguY2xpZW50X29yaWdpbl9pZCI6ImN1c3RvbWVyQ2xpZW50Iiwib3JhY2xlLm9hdXRoLnNjb3BlIjoiQ3VzdG9tZXIuSW5mbyIsInVzZXIudGVuYW50Lm5hbWUiOiJEZWZhdWx0RG9tYWluIiwib3JhY2xlLm9hdXRoLmlkX2RfaWQiOiIxMjM0NTY3OC0xMjM0LTEyMzQtMTIzNC0xMjM0NTY3ODkwMTIifQ.Y7fyCqKR6eY95SET9ddXmpCa8acLWSYoRCsZUqMadZ-eUA6GV11zfHJKUUdTcLER3TxjVb8NXLV9Hl_aTFPPxqcf6rVW_yxKrWpW6m18cDeZsmln015AZjJNdGzxrYtOBrrMuLAA58hk1h2CDplagOTDhypT_rAJGD6uDgmRrMM&state=abc

9. The Application then is able to extract the Authorization Code from the URL parameter and request the OAuth Server for an Access Token. The request would look like this in curl:

curl -i -H ‘Authorization: Basic YnJvd3NlckNsaWVudDpnOGFHZ2xaRHJQRGw3ZQ==’ -H “Content-Type: application/x-www-form-urlencoded;charset=UTF-8″ –request POST https://oxygen.mycompany.com:14101/ms_oauth/oauth2/endpoints/oauthservice/tokens -d ‘redirect_uri=https://oxygen.mycompany.com:7502/ClientWebApp/CustomerServlet&grant_type=authorization_code&code=eyJhbGciOiJSUzUxMiIsInR5cCI6IkpXVCIsImtpZCI6Im9yYWtleSJ9.eyJvcmFjbGUub2F1dGgucmVkaXJlY3QtdXJpIjoiaHR0cHM6Ly9veHlnZW4ubXljb21wYW55LmNvbTo3NTAyL0NsaWVudFdlYkFwcC9DdXN0b21lclNlcnZsZXQiLCJvcmFjbGUub2F1dGgudXNlcl9vcmlnaW5faWRfdHlwZSI6IkxEQVBfVUlEIiwib3JhY2xlLm9hdXRoLnVzZXJfb3JpZ2luX2lkIjoicGF1bG8iLCJpc3MiOiJ3d3cub3JhY2xlLmV4YW1wbGUuY29tIiwib3JhY2xlLm9hdXRoLnN2Y19wX24iOiJPQXV0aFNlcnZpY2VQcm9maWxlIiwiaWF0IjoxNDMxMTAyNjIyMDAwLCJvcmFjbGUub2F1dGgudGtfY29udGV4dCI6ImF6YyIsImV4cCI6MTQzMTEwMzUyMjAwMCwicHJuIjpudWxsLCJqdGkiOiI2OTkwNDRlZi0zM2IwLTRhNDUtYjI4MS1jYTNjMTc2NzhkNTciLCJvcmFjbGUub2F1dGguY2xpZW50X29yaWdpbl9pZCI6ImN1c3RvbWVyQ2xpZW50Iiwib3JhY2xlLm9hdXRoLnNjb3BlIjoiQ3VzdG9tZXIuSW5mbyIsInVzZXIudGVuYW50Lm5hbWUiOiJEZWZhdWx0RG9tYWluIiwib3JhY2xlLm9hdXRoLmlkX2RfaWQiOiIxMjM0NTY3OC0xMjM0LTEyMzQtMTIzNC0xMjM0NTY3ODkwMTIifQ.Y7fyCqKR6eY95SET9ddXmpCa8acLWSYoRCsZUqMadZ-eUA6GV11zfHJKUUdTcLER3TxjVb8NXLV9Hl_aTFPPxqcf6rVW_yxKrWpW6m18cDeZsmln015AZjJNdGzxrYtOBrrMuLAA58hk1h2CDplagOTDhypT_rAJGD6uDgmRrMM’ -k

Note that the Application passes its credentials enconded as 64Base in the Authorization header, the redirect URI, the grant type and the Authorization Code.

10. The OAuth Server checks the Authorization Code, if the grant type is enabled for this client and if its credentials are correct before issuing the Access Token.

11. OAuth Server send the Access Token back to the Application in the following format:

{“expires_in”:3600,”token_type”:”Bearer”,”access_token”:”eyJhbGciOiJSUzUxMiIsInR5cCI6IkpXVCIsImtpZCI6Im9yYWtleSJ9.eyJzdWIiOiJwYXVsbyIsIm9yYWNsZS5vYXV0aC51c2VyX29yaWdpbl9pZF90eXBlIjoiTERBUF9VSUQiLCJvcmFjbGUub2F1dGgudXNlcl9vcmlnaW5faWQiOiJwYXVsbyIsImlzcyI6Ind3dy5vcmFjbGUuZXhhbXBsZS5jb20iLCJvcmFjbGUub2F1dGguc3ZjX3BfbiI6Ik9BdXRoU2VydmljZVByb2ZpbGUiLCJpYXQiOjE0MzExMDM5OTgwMDAsIm9yYWNsZS5vYXV0aC5wcm4uaWRfdHlwZSI6IkxEQVBfVUlEIiwib3JhY2xlLm9hdXRoLnRrX2NvbnRleHQiOiJyZXNvdXJjZV9hY2Nlc3NfdGsiLCJleHAiOjE0MzExMDc1OTgwMDAsInBybiI6InBhdWxvIiwianRpIjoiMjQ4YjAyOTgtNWQ1Yy00ZjFkLTkzNjctZTgyYTcwY2ZiOTk5Iiwib3JhY2xlLm9hdXRoLmNsaWVudF9vcmlnaW5faWQiOiJjdXN0b21lckNsaWVudCIsIm9yYWNsZS5vYXV0aC5zY29wZSI6IkN1c3RvbWVyLkluZm8iLCJ1c2VyLnRlbmFudC5uYW1lIjoiRGVmYXVsdERvbWFpbiIsIm9yYWNsZS5vYXV0aC5pZF9kX2lkIjoiMTIzNDU2NzgtMTIzNC0xMjM0LTEyMzQtMTIzNDU2Nzg5MDEyIn0.M-OFxBY6XzPRfW295tikNl2rj_M7IqPO1RUOLoj2IyHkcYRxRlFd0kc7le4eAK0oxYSrhhNNbwrzEq25fAdDF9H8nWeMXRec69WRyDi53-BdCB8NPgrYyVcsYVcS5l5XKieMBM7Mnl0AVb3oZ77N0sRQCWkJn2S-wgYoGjHcOOE”}

12. The application is able now to make a call to a remote service – The Resource Server – using the Access Token.

13. As in the same case of the B2B, the Resource Server is another OAuth client, with the particularity that is does not have any grant or scope defined to it.

It just needs to validate the token passed by remote clients. The only detail here is that this client needs to have the option to “Allow Token Attributes Retrieval” enabled, if it wants to perform Token Introspection, that is, return additional values, rather than just receiving a “valid” status from the OAuth Server.

14. The OAuth Server validates the Token and returns additional attributes.

The validation would look like this:

{“successful”:true,”oracle_token_attrs_retrieval”:{“oracle.oauth.tk_context”:”resource_access_tk”,”exp”:1431108481000,”oracle.oauth.user_origin_id_type”:”LDAP_UID”,”oracle.oauth.user_origin_id”:”paulo”,”iss”:”www.oracle.example.com”,”prn”:”paulo”,”oracle.oauth.client_origin_id”:”customerClient”,”oracle.oauth.scope”:”Customer.Info”,”jti”:”78fc3b08-b12a-4fbc-bad8-a7e5b7041332″,”oracle.oauth.svc_p_n”:”OAuthServiceProfile”,”iat”:1431104881000,”oracle.oauth.id_d_id”:”12345678-1234-1234-1234-123456789012″}}

Note that the token, in a C2B use case, represents both the OAuth client (“oracle.oauth.client_origin_id”:”customerClient”) and the end user (“prn”:”paulo”).

15. The Resource Server returns the requested resource to the Client Application

16. The Client Application presents the results to the user agent.

 

C2B Use Case Implementation

To implement the C2B use case, a standard Java Servlet will be used, CustomerClient.java, that is very similar with the B2B use case, but it requires the user consent to allow the client application to access the user resources in its behalf.

This servlet, will obtain an Authorization Token, result of the end user authentication.

If this Servlet is protected by a OAM policy, and the user has already authenticated, the redirect to the authorization end point will provide the authentication token without the user having to login again.

With the Authorizaition Token, the Servlet can obtain and Access Token using the Authorization Code grant type, and will pass this Access Token to the Resource Server, when making the call to the Customer REST endpoint.

The Resource Service is implemented in a plain Java class using the Jersey framework to expose the Customer Service as a RESTful webservice.

The Resource Server also implements a Servlet Filter, that intercepts all incoming requests to validate the incoming Access Token before giving access to the REST Endpoint.

The relevant classes for this use case are:

  • CustomerClient.java
  • TokenProxyService.java
  • CustomerService.java
  • OAuthTokenValidationFilter.java
  • OAuthTokenValidator.java

Implementing OAuth 2 with Oracle Access Manager OAuth Services (Part IV)

Next: Implementing OAuth 2 with Oracle Access Manager OAuth Services (Part V)
Previous: Implementing OAuth 2 with Oracle Access Manager OAuth Services (Part III)
$
0
0

Introduction

This post is part IV of a series of posts about OAM’s OAuth implementation.

Other posts can be found here:

Part I – explains the proposed architecture and how to enable and configure OAM OAuth Services.

Part II – describes a Business to Business use-case (2-legged flow);

Part III  – deals with the Customer to Business use-case (3-legged flow), when the client code is running in the application server;

Part IV – describes the Customer to Business use-case (3-legged flow), when the client application runs on the browser, embedded as Javascript code;

Part V  – provides the source code and additional information for the use case implementation.

 

This post will present the C2B use-case where the Client Application is a Javascript code, running on the browser.

This is a variation of the C2B use-case presented before; in this case, the client application resides in the browser itself, embedded as javascript code.

All the API calls are made directly from the browser to the OAuth server, but this presents two problems:

 

  • First, the client credentials would be exposed, hardcoded in the javascript code, when making calls with AJAX, just like this:
    $.ajax({ 
        type: "POST",
        url: "https://oxygen.mycompany.com:14101/ms_oauth/oauth2/endpoints/oauthservice/tokens",
        data: {
            "code":code,
            "grant_type":"authorization_code"
        },
        dataType: "text",
        headers: {
            "Content-Type": "application/x-www-form-urlencoded;charset=UTF-8",
            "Authorization": "Basic d2h5c29jdXJpb3VzOnlvdWFza21l"
        },
        success: function(data){ 
            //handle token
        },
        error: function(data){
            //handle error 
        }
    });

Note that the client credentials appears in a Base64 encoded format: d2h5c29jdXJpb3VzOnlvdWFza21l, which can be easily decoded and visible to anyone accessing this web page.

 

  • Second, the AJAX call most probably would run into Cross-Domain issues. This is very likely to happen because we’re hosting our application in a web server domain different than the domain where the OAuth server is running. Although there are ways to prevent this, like changing the response headers from the OAuth server, sometimes it will just not be possible.

To avoid this situation, we are going to implement a ‘proxy’ application or ‘relay endpoint’, that will make the actual calls to the OAuth Server, thus preserving the client credentials and bypassing cross-domains restrictions imposed to AJAX calls in the web browser.

Use Case Flow

The following picture shows the flow between the different components

C2B - Javascript

1. The webpage that contains the javascript code is loaded in a browser. The embedded javascript code checks if there is an authorization code in the URL parameters.

2. If it does not find the Authorization Code, it makes a redirection to the OAuth Server Authorization URL. If the user has already been authenticated with OAM, the OAuth Server will not ask him to authenticate again, in this case the flow would proceed to step 5.

//Gets the Authorization Code
var code = getURLParameter("code");
//Not Authorized
if(typeof code == 'undefined') {
    //Redirecting to Authorization URL
    location.href = "https://oxygen.mycompany.com:14101/ms_oauth/oauth2/endpoints/oauthservice/authorize?response_type=code&client_id=browserClient&redirect_uri=https://oxygen.mycompany.com:7502/ClientWebApp/index.html&scope=Customer.Info%20UserProfile.me&state=getauthz";
    ...

3. OAuth server replies with the OAM Login Page.

4. User logs in with its credentials.

5. OAuth Server checks if the user needs to give consent for the client application to access his resources.

6. OAuth Server replies with the consent page.

7. User gives consent for the client application to access his resources.

8. OAuth Server returns the Authorization Code back to the redirect_uri as an URL parameter.

9. The javascript code embedded in the webpage extracts the Authorization Code from the URL parameter and makes a call to the Relay Endpoint requesting an Access Token, passing the Authorization Code.

} else {
    //Gets an Access Token passing Authorization Code using Proxy Application
    $.ajax({ 			
        type: "POST",
        url: "https://oxygen.mycompany.com:7502/ClientWebApp/rest/tokens",
        data: {'code':code},
        dataType: "text",
        success: function(token){
        ...

10. The Relay Endpoint makes a call to the OAuth Server requesting an Access Token, passing the Authorization Code. Since the code is running server-side, there is no cross-domain access controls imposed by browsers.

11. The OAuth Server checks the Authorization Code, checks if the grant type is enabled for this client and if its credentials are correct before issuing the Access Token.

12. OAuth Server replies with the Access Token back to the Relay Endpoint

13. The Relay Endpoint replies with the Access Token back to the Javascript code embedded in the webpage.

14. The Javascript code embedded in the webpage makes a REST call to the Resource Server passing the Access Code.

//Gets the Customer Information passing the Access Token
$.ajax({ 
    type: "POST",
    url: "https://oxygen.mycompany.com:7502/ResourceService/rest/customer",
    data: {
        "code":accessToken
    },
    dataType: "text",
    headers: {
        "Content-Type": "application/x-www-form-urlencoded;charset=UTF-8" 
    },
    success: function(data){        
        //Handles Data returned from the server
    },
    error: function(data){
        //Handles error message 
    }
});

15. The Resource Server requests a token validation with the OAuth Server

16. The OAuth Server validates the token and sends the response to the Resource Server

15. The Resource Server sends back application data to the javascript code embedded in the webpage.

C2B Use Case Implementation

To implement the C2B use case, a HTML page is used as the Client Application.

The Relay Endpoint is written in an annotated plain Java class using Jersey to expose it as a RESTful webservice.

The Resource Service is implemented in a plain Java class using the Jersey framework to expose the Customer Service as a RESTful webservice.

The Resource Server also implements a Servlet Filter, that intercepts all incoming requests to validate the incoming Access Token before giving access to the REST Endpoint.

The relevant classes/files for this use case are:

  • index.html
  • TokenProxyService.java
  • UserProfileProxyService.java
  • CustomerService.java
  • OAuthTokenValidationFilter.java
  • OAuthTokenValidator.java

Implementing OAuth 2 with Oracle Access Manager OAuth Services (Part V)

Next: Retrieving the OAM SessionID for Fun and Profit!
Previous: Implementing OAuth 2 with Oracle Access Manager OAuth Services (Part IV)
$
0
0

Introduction

This post is part of a series of posts about OAM’s OAuth implementation.

Other posts can be found here:

Part I – explains the proposed architecture and how to enable and configure OAM OAuth Services.

Part II – describes a Business to Business use-case (2-legged flow);

Part III  – deals with the Customer to Business use-case (3-legged flow), when the client code is running in the application server;

Part IV – describes the Customer to Business use-case (3-legged flow), when the client application runs on the browser, embedded as Javascript code;

Part V  – provides the source code and additional information for the use case implementation.

The previous posts explained how to configure OAM OAuth Server and how the different use-cases work.

This last post will discuss the Access Tokens and Refresh Tokens usage and Tokens Validation strategy on the Resource Server side.

Both topics are directly related to the client application design, security and overall system performance.

And last, but not least, source code will be provided so that it can be used as a starting point to understand the OAM’s OAuth basic implementation.

Access Token and Refresh Token Usage

In the examples provided in this post series, there is no Access Token reutilization or Refresh Token usage.

In a real application scenario, once the client application obtains the Access Token, it would probably make several calls using the same token, as long as it remains valid.

If the Access Token has expired –  and the client application should be able to check its validity before making a call – the client application can request another Access Token using the Refresh Token and its client credentials.

This way, the Client Application avoids making an additional call to the OAuth server every time it needs to call a service in the Resource Server.

In real world scenarios, it would really hurt the system performance, as under real load it is not practical to request a new token each time a call to the Resource Service is made.

There is also a security reason behind Refresh Tokens.

Because Access Tokens are short-lived (in contrast to long-lived Refresh Tokens), if they are compromised or the end user wishes to revoke the client application access, it can be done by revoking the Client Application Tokens (Access and Refresh tokens) and denying its access to all user resources.

This way, even if the application still has a valid Access Token or Refresh Token cached it cannot be used anymore to request access to resources or to request additional Access Tokens.

Remember, Refresh Tokens are obtained exchanging the client credentials with the Authorization Server, thus, by revoking the Client Application access (and all its tokens) the user can deny access to his resources at any time, without compromising security and other Client Applications access.

Token Validation

The token validation in the examples provided on this post rely on an additional call to the OAuth server.

This can degrade the OAuth server and Resource Service performance as these calls adds an additional chunk of time and processing to system when under load.

A good approach is to validate the token locally, using the OAuth server signing key to validate the signature and the Access Token payload.

By default, OAM uses the public certificate under the alias “oracert” to sign the OAuth tokens.

This certificate can be found in <DOMAIN_HOME>/config/fmwconfig/default-keystore.jks keystore.

To export the certificate run the following keytool command:

keytool -exportcert -alias “oracert” -keystore /u02/oracle/domains/OAMDomain/config/fmwconfig/default-keystore.jks -file oracert.der -storepass <STORE_PASS>

In a vanilla installation, the default-keystore password should be the same as OAM keystore password, which ca be found using the following WLST command:

listCred(map=”OAM_STORE”, key=”jks”)

There are lots of OAuth toolkits out there that can be used to validate tokens locally.

A simple code implementation using one of the available toolkits would look like this:

public boolean validateJWT(String token, String scope) {
    boolean isValid = false;
    try {
        JWSObject jwsObject = JWSObject.parse(token);
        JWSVerifier verifier = new RSASSAVerifier(getPublicKey("oracert.der"));
        boolean isValid = jwsObject.verify(verifier);

        if(isValid) {
            String tk_payload = jwsObject.getPayload().toString();
            JSONObject obj = new JSONObject(tk_payload);

            String userID = obj.getString("prn");

            String tokenScope = obj.getString("oracle.oauth.scope");

            if(tokenScope != null && !tokenScope.contains(scope)){
                isValid = false;
            }
        }
    } catch (Exception e) {
        isValid = false;
        e.printStackTrace();
    }
    return isValid;
}
private RSAPublicKey getPublicKey(String filename) throws Exception {
    InputStream inStream = null;
    try {
        inStream = getClass().getClassLoader().getResourceAsStream("certs/"+filename);
        CertificateFactory cf = CertificateFactory.getInstance("X.509");
        X509Certificate cert = (X509Certificate)cf.generateCertificate(inStream);
        return (RSAPublicKey)cert.getPublicKey();
    } finally {
        if (inStream != null) {
            inStream.close();
        }
    }
}

Source Code

The source code is provided “AS IS” with no express or implied warranty for accuracy or accessibility.

The code is indented to demonstrate the basic OAuth/OAM features and does not represent, by any means, the recommended approach or is intended to be used in development or productions environments.

That being said, download the source_code.

The examples are divided into two applications “ClientWebApp” and “ResourceService”.

ClientWebApp contains the code for the client part, which will obtain a OAuth Token from OAM and make calls to the REST endpoints in the ResourceService application.

ResourceService will expose REST endpoints, which will receive calls from the ClientWebApp.

The ResourceService application will validate the OAuth Token and make a decision if to reply back with the requested data or not.

The source code is self explanatory and commented so one can follow up with the implementation.

Once the OAM configuration for the OAuth artifacts is done, as explained in Part I of this post series, one can adjust the URLs in the source code, compile, and deploy both applications to any servlet container, and test the complete scenario.

I hope the posts series could be of help to understand the basics of OAM’s OAuth implementation, enjoy!


Retrieving the OAM SessionID for Fun and Profit!

Next: Multiple authentication mechanism chaining in OAM
Previous: Implementing OAuth 2 with Oracle Access Manager OAuth Services (Part V)
$
0
0

Introduction

I recently worked with a customer who needed to do some OAM session manipulation via custom code in order to implement a complex use case. While the focus of this post is not to go into details about a specific implementation, I did want to share some advice on a very necessary building block needed to do “out of band” session manipulation: retrieving the OAM Session ID.

What is the Session ID (used for)?

OAM 11g supports the concept of a server-side session (unlike previous versions where the only session state was represented by a browser cookie) and this architecture allows for a far richer set of functionality, including the ability to manipulate the server-side session through the addition of attribute values that can be considered during the evaluation of an OAM policy. Each session stored in the server session store (shared across the cluster using Coherence) is identified by a unique GUID known as the Session ID – that’s the long number you see in the folllowing screenshot, taken from the OAM Admin Console:

Session-ID

The reason this identifier is useful, though, comes when you start to look at the API Docs for the OAM Access SDK, which is the component you’ll need to use in order to do things like session manipulation from custom code. Looking specifically at the UserSession class, you’ll note that many of the constructors and utility methods require that you pass the SessionID as argument; this is a mandatory step in order to obtain a reference to an existing session in order to manipulate it. In this scenario, you don’t want to be using the UserSession class to create a brand new session.

Just a clarification at this point. Please do not interpret this post as a blanket endorsement of writing a custom Access Client as the solution to any and all problems. As always, work with your chosen OAM architect to carefully weigh up the pro’s and cons and various options available, with a strong preference for using out-of-the-box functionality, before concluding that custom code is the best way to solve your particular problem.

Assuming we’ve complied with the above caveat, done the necessary homework and concluded that the custom Access Client solution is what we have to do, what we then need is a way to obtain the Session ID from an existing authenticated user session in order to pass it to our custom code.

Using Identity Assertion to obtain the Session ID

Step 1 here is (perhaps obviously) to ensure that we place a WebGate in front of our custom code in order to ensure that there is actually a session in place and that we can use an authorization policy response to transfer information to that code via headers (the usual OAM approach). Now, for a number of very good reasons, the Session ID (a sensitive piece of information that needs to be protected) is not available as a direct policy response, in the same way that the user id, profile attributes or session attributes would be. As is perhaps clear from reading the AccessSDK documentation, you can do a lot of harm with this SessionID in your hands and, as such, it behoves you as an organization to take appropriate steps to protect this data within your code and over your network.

Treat the SessionID, in other words, just as you would a password. Do not write it into log files, do not send it over network links in clear text and take the necessary precautions to ensure that headers sent from your web tier to your app tier cannot be tampered with or spoofed. All the usual rules regarding safe and secure identity propagation apply, in other words.

With caveats and good practice advice out of the way, let’s talk about how to get this magical nugget of info into your custom code. The answer is to enable Identity Propagation for the Authorization policy protecting the URL, as per the following screenshot.

Assertion

Once you do this, you will find that a SAML assertion is sent from the WebGate to your app in a header called “OAM_IDENTITY_ASSERTION”. There’s a lot of info inside this assertion, but you’re looking for the following snippet within the XML body.

<saml:Assertion xmlns:saml=”urn:oasis:names:tc:SAML:2.0:assertion” xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance” xmlns:xs=”http://www.w3.org/2001/XMLSchema” Version=”2.0″ ID=”6714fd68-596c-4cfa-af61-91b43a5ecd2a” IssueInstant=”2015-10-23T09:34:23Z”>
<saml:Issuer>OAM User Assertion Issuer</saml:Issuer>
…..
<saml:AttributeStatement>
<saml:Attribute NameFormat=”urn:oasis:names:tc:SAML:2.0:attrname-format:uri” Name=”urn:oasis:names:tc:SAML:2.0:profiles:session:sessionId”>
<saml:AttributeValue xsi:type=”xs:string”>d8ccd738-522f-4700-a91c-fd630b70ff61|S+kAgs+tqO+Rblq6abFwllAo5J4=</saml:AttributeValue>
</saml:Attribute>
……
</saml:AttributeStatement>
</saml:Assertion>

Right there, in the bolded text, is your Session ID. Use it wisely – keep it secret, keep it safe.

Multiple authentication mechanism chaining in OAM

Next: MDC Switch – Configuring Multi-Data Center Types
Previous: Retrieving the OAM SessionID for Fun and Profit!
$
0
0

Authentication mechanism chaining

Since the inception of OAM 11g, we have been talking about authentication scheme chaining and being able to invoke multiple authentication schemes in sequence or invoke an authentication scheme based on some condition. This has been made possible since OAM R2PS2 release with the introduction of authentication status. You can PAUSE authentication process to interact with the user and resume authentication once the interaction is over. However this is all done from within one authentication module by chaining multiple authentication plug-ins instead of chaining authentication schemes. post I use this technique to implement a “user chooses the authentication method” use case described below.

Use case

When user accesses a protected resource, user should get a drop down box with all the authentication mechanisms supported. The user will choose one of the authentication mechanisms depending on user’s convenience of using certain authentication mechanism.  Here is the request flow.

  1. 1. User accesses a protected resource.
  1. 2. The user is redirected to authentication mechanism chooser page where he will get a drop down box with all the authentication mechanisms supported. The user will choose one of the authentication mechanisms from the drop down box and submit the choice.
  1. 3. A custom authentication plug-in (Authentication Chooser plug-in) reads user choice and depending on authentication mechanism chosen, the user is redirected to respective credential collector page by credential collector plug-in. Each authentication mechanism has to invoke different credential collector plug-in. This is accomplished by authentication plug-in orchestration in the authentication module. Ex: If user chooses FORM based login, then the custom plug-in will return SUCCESS otherwise it will return FAILURE. Based on SUCCESS and FAILURE, you can orchestrate respective credential collector plug-in. This works fine when there are just two authentication mechanisms supported. If there are more, then FAILURE has to invoke one other custom authentication plug-in. You will need N-1 (‘N’ is the number of authentication mechanisms that are supported) custom authentication plug-ins to redirect user to respective credential collector plug-ins.
  1. 4. User is now challenged for chosen credentials by credential collector plug-in. When user is challenged for credentials, Authentication context status is set to PAUSE.
  1. 5. When user submits credentials with authentication context (OAM_REQ cookie), OAM resumes authentication from the next plug-in in sequence. The next plug-in in sequence has to process those credentials.
  1. 6. If those credentials are correct, then a credentials processing plug-in returns SUCCESS and user is redirected to protected resource that the user intended to access.

There are two aspects of the implementation that are different than just FORM or Kerberos authentication process. One of them is the need of custom authentication plug-in and the second one is plug-in orchestration in authentication module.

Authentication plug-in orchestration

Here are all the steps involved in authentication in sequence along with some description, plug-in name, Is it custom plug-in or Out-Of the Box plug-in. Diagram below the table shows orchestration of the plug-ins.

 

Step Name

Plug-In Name (OOB/Custom)

Description

ChallengeChoice CredentialsChallengePlugin (OOB) This plug-in will forward Authentication request to Authentication chooser page that shows drop down box with all the authentication mechanisms supported.
AuthSelector (Authentication chooser plug-in) CustomAuthSelector (Custom) This plug-in will read user choice and return SUCCESS or FAILURE as described in the last section.
ChallengeForCreds CredentialsChallengePlugin (OOB) This plug-in will forward the request to login form.
ValidateUser UserIdentificationPlugin (OOB) This is UserIdentificationPlugin to search the user
ValidatePassword UserAuthenticationPlugin (OOB) This is UserAuthenticationPlugin that validates the password
ChallengeForToken CredentialsChallengePlugin (OOB) This plug-in is invoked when user chooses Kerberos authentication. It redirects user to Kerberos credentials collector page.
ReadKerberos KerberosTokenReader (Custom) This plug-in reads Kerberos token from HTTP header and adds it to OAM credentials object.
ValidateToken KerberosTokenAuthenticator (OOB) This plug-in reads Kerberos token from OAM credentials object and validates it.
KerberosUserIdentification UserIdentificationPlugin (OOB) This is UserIdentificationPlugin to search for the logged in user in LDAP.

 

 

PluginOrchestration

As I mentioned before, if there are N authentication methods to support, you will need N-1 custom authentication plug-ins to process user choice and route to respective credential collection URL. Below example shows authentication plug-in orchestration to support 3 authentication methods using two custom authentication plug-ins as highlighted. One other interesting observation or guideline so to say is, there are three successful orchestration completions one for each authentication method supported.

 

MultipleCustomAuthnPlugins

Authentication plug-ins used

Credentials challenge plug-ins

CredentialsChallengePlugin is Out-Of the Box plug-in used by ChallengeforCreds, challengeForToken and challengeChoice steps in the flow. challengeforCreds and challengeChoice steps forward the request to respective login pages as shown in the screen shot below. However challengeForToken step redirects the request to Kerberos challenge URI. Kerberos challenge URI is,

/oam/CredCollectServlet/WNA?spnegotoken=string&challenge_url=%2Foam%2FCredCollectServlet%2FWNA&request_id={KEY_REQUEST_ID}&authn_try_count=0&locale=en_US

/oam/CredCollectServlet/WNA is OAM Out-Of the Box Servlet that challenges user for Kerberos token.

Please note that URI contains request_id query parameter. The value is {KEY_REQUEST_ID}. This is required to carry forward same authentication context. I have to pass this on because this is HTTP redirect request and HTTP being state less protocol, will lose that information if I do not pass it. However in case of challengeForCreds, because it is HTTP forward request, the login page will get it without me passing it as query parameter.

One other credentials collector supported by OAM is, x509Certificate. Below is the URL for x509 certificate credentials collector if you need to support that authentication mechanism as well.

/oam/CredCollectServlet/X509?challenge_url=https%3A%2F%2Foamvm.example.com%3A14101%2Foam%2FCredCollectServlet%2FX509&request_id={KEY_REQUEST_ID}&authn_try_count=0&locale=en_US

 

ChallengeChoice

 

ChallengeToken

 

 

Authentication chooser plug-in

You have to read authentication method chosen and return either success or failure as shown in the sample code below. Please note that I am also reading for request_id and returning error if I do not find it. What that also tells you is, authentication chooser login page should read request_id and pass it as hidden FORM parameter just like you do in the custom FORM login pages.

AuthChooserPlugin

KerberosTokenAuthenticator plug-in

KerberosTokenAuthenticator plug-in validates Kerberos token. It is Out-Of the Box plug-in. It reads Kerberos token from OAM credentials object and validates that using keytab.

KerberosTokenAuthenticator

KerberosTokenReader plug-in

KerberosTokenReader is one other custom plug-in in the sequence. When user submits Kerberos token, the next step is to validate token. KerberosTokenAuthenticator is Out-Of the Box plug-in that can validate the token. However it looks for Kerberos token in OAM credentials object while user submits the token as Authorization HTTP header. So KerberosTokenReader reads Kerberos token from HTTP request and adds that into OAM credentials object as shown below.

KerberosTokenReader

Similarly X509CredentialExtractor looks for X509 certificate in OAM credentials object. If you are planning to use that within the flow, you will have to write X509CertReader plug-in that reads certificate from HTTP request and adds that into OAM credentials object with “PluginConstants.KEY_CERTIFICATE” as the key. Or you can make generic plug-in to read source (HTTP Request), destination (OAM Credentials) and object (Negotiate header) from plug-in configuration and moves the object from source to the destination.

User Identification Plugin

This is again Out-Of the Box plug-in that reads user information and searches for the user in LDAP.

User Authentication Plugin

This plug-in is used for FORM based login. The plug-in validates user password by binding to LDAP with user DN that it gets from previous plug-in in the sequence (UserIdentificationPlugin) and user password.

Conclusion

There are many more such use cases that can be solved with this approach. In this case, we relied on end user to choose what authentication mechanism (s)he wants to use. We could as well read whether or not user is in the domain and challenge for kerberos else challenge for FORM login. One other use case is to check if user is using mobile device or desktop and change authentication mechanism based on that. FIDO is gaining popularity. We can check if device supports FIDO authentication. If it does then challenge for FIDO authentication, else challenge with login FORM.

MDC Switch – Configuring Multi-Data Center Types

Next: OAM 11g Webgate Tuning
Previous: Multiple authentication mechanism chaining in OAM
$
0
0

INTRODUCTION

This post discusses the steps required to configure a “master” data center to a “clone” data center and visa-versa.

If you are not familiar with Multi-Data Center (MDC) implementation and Automated Policy Synchronization (APS) please read the following links:

http://www.ateam-oracle.com/multi-data-center-implemenation-in-oracle-access-manager/

http://www.ateam-oracle.com/automated-policy-synchronization-aps-for-oam-cloned-environment/

MAIN ARTICLE

Use Case: Customer wants to convert an existing data center type from “master” to “clone” and the “clone” data center to a “master”.

One scenario for this use case is where the customer is adding a new data center and wants to designate the data center as the “master” and set the old “master” site as “clone”.  Other scenarios include configuring disaster recovery (DR) sites for example.

 

Implementation

I like to automate things where applicable so after each step below I provide a simple bash script via gitlab link that you can use as a baseline for your environment. Scripting the process is helpful for quickly switching the data center type. There are some caveats that I will be discussing after each step as well.

NOTE: In order for the MDC switch to work, both the “master” and “clone” Weblogic Administration servers must be up and running.

The steps provided below was tested on Oracle Access Manager (OAM) version 11.1.2.3.3 (PS3/BP03) and Weblogic 10.3.6.

  • Step 1) Disable/Delete existing APS agreement.

a) First get the list of agreements:

curl -k -u weblogic:Welcome1 ‘http://dc1.ateam.com:7001/oam/services/rest/_replication/agreements

b) Using the replication agreement ID above, disable the consumer agreement:

curl -u weblogic:Welcome1 -H ‘Content-Type: application/json’ -X PUT ‘http://dc1.ateam.com:7001/oam/service/rest/_replication/201409231329353668′ -d ‘{“enabled”:”false”,”replicaType”:”CONSUMER”}’

c) Disable supplier

curl -u weblogic:Welcome1 -H ‘Content-Type: application/json’ -X PUT ‘http://dec1.ateam.com:7001/oam/service/rest/_replication/201409231329353668′ -d ‘{“enabled”:”false”,”replicaType”:”SUPPLIER”}’

d) Delete both the consumer and supplier agreements

curl -u weblogic:Welcome1 -H ‘Content-Type: application/json’ -X DELETE ‘http://dc1.ateam.com:7001/oam/services/rest/_replication/201409231329353668′

Here is a link to the script:

https://gitlab.com/vkalra/OAMScripts/blob/master/removeAPS.sh

First notice that the curl command requires a user name and password. The user here must be part of the ‘system store’. By default the system store is WebLogic embedded LDAP. For a better understanding check out this link:

http://www.ateam-oracle.com/oam-11g-configuring-data-sources/

Now if you changed the system store after the replication agreement was created you may have issues removing the agreement. You have two options here; one you can revert the system store configuration and try the script again or you can delete the replication agreement directly from the Database.

Below is a screen shot of SQL Developer that shows the value of the replication agreement in the database. From SQL Developer you can delete the replication agreement. Make sure that you remove both entries from the master and clone database. The replication agreement can be found under the AM_REPLICATION_SETTINGS table.

 

OEL6.6 DC1 (APS working with PS3 base and external LDAP) [Running] - Oracle VM VirtualBox_034

  • Step 2) Modify Clone DC

Run wlst script:

connect() (enter parameters to connect)

domainRuntime()

a) Set write enabled flag to ‘true’

setMultiDataCenterWrite(WriteEnabledFlag=”true”)

b) Set to data center to “master”

setMultiDataCenterType(DataCenterType=”Master”)

  • Step 3) Modify Master DC

Run wlst script:

connect() (enter parameters to connect)

domainRuntime()

a) Set data center type to clone

setMultiDataCenterType(DataCenterType=”Clone”)

b) Set write enabled flag to ‘false’

setMultiDataCenterWrite(WriteEnabledFlag=”false”)

Here is a link to the script:

https://gitlab.com/vkalra/OAMScripts/blob/master/mdcSwitch.py

 

  • Step 4) Setup a new replication agreement

a) Make sure replication is enabled

curl -u weblogic:Welcome1 ‘https://dc2-ateam.com:7001/oam/services/rest/_replication/hello’

b) Create the agreement and note the agreement ID

Make sure the host is pointing to the new master site (dc2)

curl -u weblogic:Welcome1 -H ‘Content-Type: application/json’ -X POST ‘http://dc2.ateam.com:7001/oam/services/rest/_replication/setup’ -d  ‘{“name”:”DC22DC1″, “source”:”dc2East”,”target”:”dc1West”,”documentType”:”ENTITY”}’

{“enabled”:”true”,”identifier”:”201510160547491349″,”ok”:”true”,”pollInterval”:”900″,”startingSequenceNumber”:”1761″,”state”:”READY”}

c) Shorten the poll interval for testing purposes

curl -u weblogic:Welcome1 -H ‘Content-Type: application/json’  -X PUT ‘http://dc2.ateam.com:7001/oam/services/rest/_replication/201409040157218184′ -d ‘{“pollInterval”:”60″,”replicaType”:”consumer”}’

Here is the link to the script:

https://gitlab.com/vkalra/OAMScripts/blob/master/createAPS.sh

Once this step is complete, you will need to restart the clone admin and managed srevers as per the documentation:

Once replication agreement is created successfully, the clone/consumer will start polling for changes from next restart of clone AdminServer onwards. The default poll interval for changes is ‘900’ seconds or 15 mins. The poll interval can be changed by executing an edit replication agreement command.

Done!

OAM 11g Webgate Tuning

Next: Cloud Security: Federated SSO for Fusion-based SaaS
Previous: MDC Switch – Configuring Multi-Data Center Types
$
0
0

INTRODUCTION

This post is part of a larger series on Oracle Access Manager 11g called Oracle Access Manager Academy. An index to the entire series with links to each of the separate posts is available.

People typically are introduced to Webgate tuning in one of two ways, either forced into it because of a crisis or actively preparing an environment to do some aggressive load testing.  Hopefully you are in the later group.  Unfortunately, there is still a lot of mystery behind tuning some of these Webgate parameters.  Creating a comprehensive article to cover all aspects of tuning is a real challenge.  That said, this article will be focused on what I feel are the most important tuning parameters; 1) Max Connections, including the relationship between Max Connections and Max Number of Connection, 2) the Failover Threshold, and 3) the AAA Timeout Threshold.  If you can grasp the concepts around these few important key parameters your success in getting better performance and stability out of the Webgates and Access Servers will greatly increase.

Quick Overview

Knowledge in this article is based on extensive experience in the field, discussions with Oracle Webgate developers, and of course invaluable peers.  As I already mentioned in the introduction I will break out the Webgate tuning into three areas to help make it a little easier to digest.   Each of the three parameters are not necessarily relate to each other or dependent, so you are free to jump to the section you are interested in.  However, I highly advise that you spend time reading the entire article before making any major tuning changes.  Below is a screenshot of an 11gR2PS3 (OAM 11.1.2.3.0) Webgate definition that highlights the parameters I will cover plus any associated field; all settings are R2PS3 default values.

 

img1_webgate_def

 

Max Connections — Not so Literal

The Max Connections parameter can reap some big improvements in performance, but beware — increasing the value does not necessarily equate to increased performance and in fact can even have a negative impact. The official Oracle OAM 11g 11.1.2 Administration Guide says, “Max Connections is the maximum number of connections that a Webgate can establish with the Access Server.” This statement is a bit confusing and could lead you to believe that by applying Max Connections value X will only send X number of connections to the Access Server, but that is completely false.

I want to cover more detail on the Max Connection parameter, but first things first, we need to understand how connections work with web servers and how it relates to the Webgate module. To keep this simple I want to focus my examples using OHS (Oracle HTTP Server) especially since the majority of the audience use OHS. As a side note OHS is basically Apache from a fundamental level. Therefore, my explanations with OHS going forward will also apply to Apache. If you use a different 11g Webgate supported web server, how connections work can be different so please extrapolate this information and try to apply it to your web server environment.

Worker or Pre-Fork Mode

OHS will run in one of two modes, “Worker” or “Pre-Fork”. The default in OHS is Worker mode, but with Apache it can depend on how it was compiled though typical implementations use Worker mode.  Be sure to verify what mode you are running in. As far as Worker mode, it uses multiple child processes with several threads for each process. Each thread will handle one connection at a time.

Now, the thing that is important to understand here is that the Webgate module is actually instantiated by the child processes directly, rather than by the OHS parent process. Again focusing purely on the multi-threaded “Worker” mode, a number of directives within the web server configuration file control exactly how many child processes will be spawned based on the number of incoming requests. From a Webgate point of view, we must bear in mind that each of these child processes will open its own pool of connections to the Access Servers, as defined by the Max Connections setting in the Webgate profile.

As a working example, let us specify Max Connections as “12” and our web server is configured to spawn up to 20 child processes, the total number of connections from the web server as a whole to the OAM servers will thus be 12 Max Connections times 20 child processes for a total of 240 connections; (12 x 20 = 240). We should always consider this multiplicative effect in mind when defining “Max Connections”, since we don’t want to end up opening too many connections and risk overloading the Access Servers. In the sections that follow, this multiplicative effect will not be explicitly called out, but please remember that it still applies in every case. So let’s apply another example so we fully understand the ramification of both the Max Connection and OHS configuration settings and how they relate.

Take for example the default mpm_worker_module section from an OHS httpd.conf file; shown below. We see ThreadsPerChild is set to 25, MaxClients is 150, and StartServers equals 2. The MaxClients value basically limits the maximum number of threads that can be opened by OHS while StartServers says open up 2 child processes at start up. That means at start up we will immediately get 2 children times 25 threads for a total of 50 threads. We know that each child has X WebGate connections where X is defined by the Max Connection setting in the webgate profile.  So if our Max Connection is 12 we will immediately have a total of 24 connection (2 StartServers x 12 Max Connections = 24 Webgate connections).  As traffic increases, OHS/Apache will spawn more children and therefore more webgate connections until the MaxClients limit is reached.  With MaxClient set to 150 and ThreadsPerChild set to 25, we can expect somewhere between 6-8 children max (the extra are due to the spare threads portion of the algorithm).  With 12 connections per child this means a maximum of somewhere between 72 and 96 connections for our example OHS/Apache server.

 

<IfModule mpm_worker_module>
     StartServers         2
     MaxClients         150
            ServerLimit                      6
     ThreadsPerChild     25
     MinSpareThreads     25
     MaxSpareThreads     756
     MaxRequestsPerChild  0
     AcceptMutex fcntl
     LockFile
</IfModule>

 

If Max Connections is changed to 24 then the number of connections goes to 1,200 (25 ThreadsPerChild x 2 StartServers x 24 Max Connections = 1,200 Webgate connections). As the web server accepts greater loads it will open up additional threads as needed. Each thread that is opened spawns 25 new children. We can easily see how the Webgate connections can multiply to become hundreds or even thousands of connections from one OHS server to each Access Server. The only throttle is MaxClients, which limits the total number of threads OHS will open. And keep in mind a production environment will have several OHS servers so the load on the Access Servers can grow quite fast. It is important when tuning Max Connections to monitor the utilization of CPU and Memory, plus the TCP connections on each Access Server as you tweak Webgate Max Connections or even the OHS ThreadsPerChild and MaxClients values. It is also important to understand that the specific number of threads per process is governed by the setting “ThreadsPerChild”.  The take away for this lesson is that a few Max Connections can go a long way, but too much of a good thing can be bad. Remember Mom always knew best when she said everything in moderation.

 

img2_http_threads

 

Now if your web server is configured for Pre-Fork mode, be especially careful because each request to the web server is handled by a dedicated (i.e. single-threaded) child process.  It follows that the maximum number of child processes – and hence the total number of Access Server connections – can quickly grow to a very large number.  I am sure you are asking, so what is a good value for Max Connections?  As for a magical recommended number, besides calculating the total sum based on the Max Number of Connections from each primary Access Server (more on that in the next section), unfortunately there is no sweet spot.  The value needs to be determined based on experimenting with load tests and recording the results that can be compared to see what values reap the best performance.  No implementation is alike, and as many deployments I have seen I have equally seen as many different values.   Now before you decided on the Max Connections value, you need to read the next section.

 

Making the Connection to Max Connections

There is no pun in the connection between Max Connections and Max Number of Connections. In a nutshell, the value for the Max Connections parameter should be the sum of all the Max Number of Connections from each Primary Server. Take the following diagram as an example.

maxconn_01

The value for Max Connections in the diagram is 12. If you add up the Max Number of Connections from each of the three Primary Servers it totals 12 (4+4+4=12).

Let’s take another example, but this time change OAM 3 primary Access Server to a secondary server, and also update the Max Number of Connections value for each OAM Server from 4 to 6.

maxconn_02

The first thing I want to point out is that the secondary Access Server will not get requests from the Webgate until connections to any primary Access Server fall below the Failover Threshold; more on that later. Since we have two primary OAM servers with Max Number of Connections values of 6 each, the total Max Connections value for the Webgate would be 12 (6+6=12); it is pretty simple. Now that we understand how to get the value for Max Connections parameter, you maybe wondering about what value to even use for Max Number of Connections; 4, 6, 20, 100? Good question, and fortunately Chris Johnson wrote a great article on this very subject, “How many connections do I need from the WebGate to the OAM Server?”. Again, it must be called out that the number you define in the Webgate profile will be multiplied by the number of Web Server child processes to determine the actual number of connections – so a little can often go a long way!

 

Does each Max Number of Connections need to be Symmetrical?

So far in my examples I have made each OAM server Max Number of Connections the same or symmetrical, but you don’t necessarily have to do that. You can optionally add more connections to different primary servers if you want more requests to go to any specific server. This strategy is basically a type of load balancing using the Webgate Max Number of Connections configuration value instead of using an actual physical load balancer appliance; take the following diagram as an example.

maxconn_03

Notice that OAM 1 primary server has 8 Max Number of Connections while OAM 2 and OAM 3 primary servers have 4 each. So the total Max Connections value would be 16 (8+4+4=16). In this particular configuration OAM 1 server would get double the number of connections from the Webgates as the other two primary OAM servers. One reason to do this would be that OAM 1 is a much larger server, more memory, etc. and can handle more traffic, or maybe OAM 1 is physically closer to the Webgate so it can process requests much faster. In reality even though this is an option, I have never really seen this in practice because normally all the servers have the equivalent sized hardware, are in the same network, and therefore there is no need to distribute more requests to any one server. That said, I did want to at least bring this up so you understand that there are options for various reasons if you so decide it makes sense.

 

The Skinny on Failover Threshold

The latest (At the time of this post) official 11g Access Manager documentation in section Table 16-3 Elements on Expanded 11g and 10g WebGate/Access Client Registration Pages says the Failover Threshold parameter is “Number representing the point when this Webgate opens connections to a Secondary OAM Server.” It also gives an example, if 30 were used as a value, and the number of connections to primary servers drops to 29, connections begin to open up to the secondary Access Server; the default value is 1. This description kind of gives an idea of what is happening, but no recommendations and some find it confusing. So I wanted to add some of my experience with recommendations.

 

1. First, the word “Failover” in the parameter name is exactly what it means. As connections are lost from each primary OAM server, the Webgate will then try to make up that connection by connecting to a secondary OAM server; hence the word “Failover”.  So a big note here, this setting only works if there are at least one or more secondary OAM servers defined in the Webgate profile. The parameter Failover Threshold will do nothing if there is no secondary OAM server defined.

failover_02

2. Second, the word “Threshold” in the parameter name is talking about at what point do connections begin to go over to the secondary OAM server(s).   Based on the official documentation, which is correct, if the Failover Threshold is set to 6 where the Max Number of Connections is also set to 6, then as soon as the number of connections going from the Webgate to the OAM server drops below the Failover Threshold of 6, connections will start to be sent to the secondary OAM server(s).   If there are two secondary OAM servers, the first in the list will be the one getting all the connections. As soon as the first secondary OAM server fills up its Max Number of Connections, the second secondary OAM server will start getting connections. Are you following?

So the big question is what is the best setting? My recommendation is two fold.

1. If you DO have Secondary OAM Servers configured:
Set the Failover Threshold value equal to the Max Number of Connections only if you have at least one secondary OAM server. Take my examples above, if the OAM server Max Number of Connections is 4, then set the Failover Threshold to 4. The reason for this is that you engage all the processing power needed as connections drop from any one primary OAM server since the secondary OAM server will start picking up the slack. As soon as the primary server having connection problems corrects itself, the Webgate will start failing back to the primary OAM server and slowly drop the connections from the secondary server until all the Max Number of Connections are met.

2. If you DO NOT have Secondary OAM Servers configured:
If you decide not to configure any secondary OAM server, you can leave the Failover Threshold value to the default of 1 because it will never be used. Remember, Failover Threshold requires a secondary OAM server to be configured. In practice, most clients like to see all their hardware provide some value, which means keep them all working to get their money worth. So I will typically see all OAM servers configured as primary servers; there is nothing wrong with this. That said, I have also seen various configurations with a mix of primary and secondary servers in a criss cross fasion that is a bit more complicated, but certainly has merrits too depending on the situation.

If you follow either of the points above you should have a solid configuration.

 

AAA Timeout Threshold

The AAA Timeout Threshold parameter setting determines how long the Webgate will wait on a connection response before it gives up and attempts to request a new connection. For example let’s say the Webgate has a connection opened, and a request comes through to validate some credentials. This process normally should take a fraction of a second, but there could be all sorts of variables to make this request take much longer. If the wait for the response is longer than the AAA Timeout Threshold, it will abandon the connection for that request, toss it back in the pool, and open a new connection to try again.

For most of OAM’s life (prior to R2 PS3), the default value for AAA Timeout Threshold is “-1” (minus one). The -1 is a special value that tells the Webgate to use the operating systems TCP timeout, which could easily be 2 minutes or even more! I have seen actual cases in practice where something goes awry with some Access Server and while the Webgate tries to connect to the Access Server or get some response from it, the Webgate keeps trying for a long time because the AAA Timeout Threshold was set to the default -1. As each connection tries for a very long time, the Webgate begins to get into a state that gives impression it is down when in reality the Webgate is doing what it was told, and that was to wait for a long time before retrying. When all the connections start doing this we have an OAM zombie apocalypse problem. Zombies are bad, but we can try to avoid this behavior by shortening that wait time.

The recommended value is any where from 5 to 10; this is in seconds. For example if you set the AAA Timeout Threshold to 5, the Webgate will open its connection, send its request, and expect to get a response back in say 5 seconds. If not, then it opens a new connection and tries again while the old connection is just freed up and tossed back into the pool. If the value is set to be shorter, like say 1 second, an authentication or authorization request could possibly take longer because the Access Server is waiting for a long LDAP search to be returned, and therefore send us into a whirling tail spin because you would never get your request completed since there is not enough time allotted for such an LDAP search. So we have found that a 5 – 10 seconds value seems to be a fair and balanced approach.  In R2 PS3 the default is now 5 seconds, which is reasonable.

 

User-Defined Webgate Parameters

One worthy parameter to mention that many may not know about is “client_request_retry_attempts”. A description of this parameter can be found in the latest (at the time of this article) in the official Oracle online document https://docs.oracle.com/cd/E40329_01/admin.1112/e27239/register.htm#AIAAG5856. The official description says; “WebGate-to-OAM Server timeout threshold specifies how long (in seconds) the WebGate waits for the OAM Server before it considers it unreachable and attempts the request on a new connection.” This at first seems similar to the AAA Timeout Threshold, but the difference is that this parameter is more about how many times the WebGate will retry its request before attempting the secondary server.

So if the AAA Timeout Threshold is set to 5 seconds, it will time out that connection after 5 seconds if there is no response, but using the client_request_retry_attempts tells the Webgate how any times it will attempt to retry that connection. If the value is set to 2, then the Webgate will wait 5 seconds (Assuming the AAA Timeout Threshold is set to 5), and if it times out it will try up to 2 times before timing out the connection. This configuration may be useful if you think a network connectivity between the Webgates and the Access Servers are not stable and you want the Webgate to at least try more than once before closing its connection.

 

Summary

I realize there are a lot of details in this blog, but it is all very useful and you may need to read each section carefully to absorb the data.  I can say that tuning the Webgate profile is a very important part of an OAM deployment and can save you lots of late nights worrying about performance or outages.  Good luck and be sure to load test your configurations before going live.

Cloud Security: Federated SSO for Fusion-based SaaS

Next: Exploring OAM’s SAML Identity Assertion
Previous: OAM 11g Webgate Tuning
$
0
0

Introduction

To get you easily started with Oracle Cloud offerings, they come with their own user management. You can create users, assign roles, change passwords, etc.

However, real world enterprises already have existing Identity Management solutions and want to avoid to maintain the same information in many places. To avoid duplicate identities and the related security risks, like out of sync passwords, outdated user information, or rogue user accounts of locked accounts, single sign-on solutions are mandatory.

This post explains how to setup Federated Single Sign-on with Oracle SaaS to enable users present in existing Identity Management solutions to work with the Oracle SaaS offerings without additional user setup. After a quick introduction to Federated Single Sign-on based on SAML, we explain the requirements and the setup of Oracle SaaS for Federated Single Sign-on.

Federated Single Sign-on

Federated Single Sign-on or Federated SSO based on SAML Web Browser Single Sign-on is a widely-used standard in many enterprises world-wide.

The SAML specification defines three roles: the principal (typically a user), the Identity Provider, and the Service Provider. The Identity Provider and the Service Provider form a Circle of Trust and work together to provide a seamless authentication experience for the principal.

SAML Login Flows

The most comomly used SAML login flows are Service Provider Initiated Login and Identity Provider Initiated Login as shown below.

Service Provider Initiated Login

The Service Provider Initiated Login is the most common login flow and will be used by users without explicitely starting it. Pointing the browser to an application page is usually all that is needed.

Here the principal requests a service from the Service Provider. The Service Provider requests and obtains an identity assertion from the Identity Provider and decides whether to grant access to the service.

SAML_SP_Initiated_Login_0

Identity Provider Initiated Login

SAML allows multiple Identity Provider configured for the same Service Provider. Deciding which of these Identity Providers is the right one for the principal is possible but not always easy to setup. The Identity Provider Initiated Login allows the principal to help here by picking the correct Identity Provider as a starting point. The Identity Provider creates the identity assertion and redirects to the Service Provider which is now able to decide whether to grant access to the service.

SAML_IdP_Initiated_Login_0

Oracle SaaS and Federated SSO

Here Oracle SaaS acts as the Service Provider and builds a Circle of Trust with a third-party, on-premise Identity Provider. This setup applies to all Fusion Applications based SaaS offerings (like Oracle Sales Cloud, Oracle HCM Cloud, or Oracle ERP Cloud) and looks like this.

SaaS_SP_OnPrem_IDP
The setup requires a joint effort of the customer and Oracle Cloud Support.

Scenario Components

The components of this scenario are:

  • Oracle SaaS Cloud (based on Fusion Applications, for example, Oracle Sales Cloud, Oracle HCM Cloud, Oracle ERP Cloud)
  • Any supported SAML 2.0 Identity Provider, for example:
    • Oracle Identity Federation 11g+
    • Oracle Access Management 11gR2 PS3+
    • AD FS 2.0+
    • Shibboleth 2.4+
    • Okta 6.0+
    • Ping Federate 6.0+
    • Ping One
    • etc.

The list of the supported SAML 2.0 Identity Providers for Oracle SaaS is updated regularly, and is available as part of the Fusion Applications Technology: Master Note on Fusion Federation (Support Doc ID 1484345.1).

Supported SAML 2.0 Identity Providers

The Setup Process

To setup this scenario Oracle Cloud Support and the Customer work together to create a operational scenario.

Setup of the On-Premise Identity Provider

To start the setup, the on-premise Identity Provider must be configured to fulfill these requirements:

  • It must implement SAML 2.0 of the Federation protocol.
  • The SAML 2.0 browser artifact SSO profile has been configured.
  • The SAML 2.0 Assertion NameID element must contain one of the following:
    • The user’s email address with the NameID Format being Email Address
    • The user’s Fusion uid with the NameID Format being Unspecified
  • All Federation Identity Provider endpoints must use SSL.
Setup of the Oracle SaaS Cloud Service Provider

Once the on-premise Identity Provider has been configured successfully, the following table outlines the process to request the setup of Oracle SaaS as Service Provider for Federated SSO with the customers on-premise Identity Provider:

Step Customer Oracle
1. File a Service Request to enable the required Oracle SaaS instance as Service Provider. The Service Request must follow the documented requirements.
(See Support Doc ID 1477245.1 or 1534683.1 for details.)
2. Approves the Service Request
3. Receives a document that describes how to configure the on-premise Identity Provider for the Service Provider.
4. When the conformance check has been done successfully, the Identity Provider Metadata File as XML file must be uploaded to the Service Request.
5. Configures the Service Provider in a non-production SaaS environment. When this is completed the Service Provider Metadata will be attached to the Service Request as an XML file for the customer. This file includes all the required information to add the Service Provider as a trusted partner to the Identity Provider.
6. Download the Service Provider metadata file and import it into the Identity Provider.
7. Adds the provided Identity Provider metadata to the Service Provider setup.
8. After the completion of the Service Provider setup, publishes a verification link in the Service Request.
9. Uses the verification link to test the features of Federated SSO.

Note: No other operations are allowed during this verification.

10. When the verification has been completed, update the SR to confirms the verification.
11. Finalize the configuration procedures.
12. Solely responsible for authenticating users.

When Federated SSO has been enabled, only those users whose identities have been synchronized between the on-premise Identity Provider and Oracle Cloud will be able to log in. To support this, Identity Synchronization must be configured (see below).

Identity Synchronization

Federated SSO only works correctly when users of the on-premise Identity Store and of the Oracle SaaS identity store are synchronized. The following sections outline the steps in general. The detailed steps will be covered in a later post.

Users are First Provisioned in Oracle SaaS

The general process works as follows:

Step Oracle SaaS On-premise Environment
1. Setup Extraction Process
2. Download Data
3. Convert Data into Identity Store Format
4. Import Data into Identity Store

Users are First Provisioned in On-Premise Environment

It is very common that users are already exiting in on-premise environments. To allow these users to work with Oracle SaaS, they have to be synchronized into Oracle SaaS. The general process works as follows:

Step Oracle SaaS On-premise Environment
1. Extract Data
2 Convert data into supported file format
3 Load user data using supported loading methods

References

Viewing all 95 articles
Browse latest View live