Tuesday, September 16, 2014

OAM Authentication iOS App


Oracle Mobile and Social Access Service is a fully integrated, server-based solution designed to secure mobile access to applications leveraging the enterprise’s existing OAM 11g infrastructure.  In this blog I am going to show how to use the Oracle’s iOS SDK to demonstrate the login/logout feature. This article assumes you have OAM 11g as well as the Mobile and Social component installed and configured.

Create new Single View Application

I called it OAMLogin

Add Navigation Controller to the main storyboard Main_iPhone.storyboard

Delete the Table View Controller – Root from the storyboard and move the starting point (arrow) to the Navigation Controller:

Control Click on Navigation Controller and drag to OAM View Controller and set it as root view:
Add Login button to the Navigation:
Update the oamViewController header and implementation as follows. After this we will have just a shell with login/logout behavior but no real authentication happening.
oamViewController.h
#import
@interface oamViewController : UIViewController {    bool isAuthenticated;    NSString *username; } @property (strong, nonatomic) IBOutlet UILabel *welcomeLabel; @property (nonatomic,assign) bool isAuthenticated; @end 
oamViewController.m
#import "oamViewController.h"@interface oamViewController () @end@implementation oamViewController @synthesize isAuthenticated; - (void)viewDidLoad {    [super viewDidLoad];    // Do any additional setup after loading the view, typically from a nib.    if(!isAuthenticated)    {        self.navigationItem.prompt = nil;        UIBarButtonItem *rightButton = [[UIBarButtonItem alloc]                                        initWithTitle:@"Login"                                        style:UIBarButtonItemStyleBordered                                        target:self                                        action:@selector(doLogin:)];        [self.navigationItem setRightBarButtonItem:rightButton                                          animated:YES];    }    else    {        self.navigationItem.prompt = nil;        UIBarButtonItem *rightButton = [[UIBarButtonItem alloc]                                        initWithTitle:@"Logout"                                        style:UIBarButtonItemStyleBordered                                        target:self                                        action:@selector(doLogout:)];        [self.navigationItem setRightBarButtonItem:rightButton                                          animated:YES];    } }- (IBAction)doLogin:(id)object {    [self doLogin]; }- (void) doLogin {    isAuthenticated =YES;    self.navigationItem.prompt = nil;    UIBarButtonItem *rightButton = [[UIBarButtonItem alloc]                                    initWithTitle:@"Logout"                                    style:UIBarButtonItemStyleBordered                                    target:self                                    action:@selector(doLogout:)];    [self.navigationItem setRightBarButtonItem:rightButton                                      animated:YES];    [self.welcomeLabel setText:[NSString stringWithFormat:@"Welcome %@", @""]]; }- (IBAction)doLogout:(id)object {    [self doLogout]; }- (void) doLogout {    isAuthenticated =YES;    self.navigationItem.prompt = nil;    UIBarButtonItem *rightButton = [[UIBarButtonItem alloc]                                    initWithTitle:@"Login"                                    style:UIBarButtonItemStyleBordered                                    target:self                                    action:@selector(doLogin:)];    [self.navigationItem setRightBarButtonItem:rightButton                                      animated:YES];    [self.welcomeLabel setText:[NSString stringWithFormat:@"Welcome Guest"]]; }- (void)didReceiveMemoryWarning {    [super didReceiveMemoryWarning];    // Dispose of any resources that can be recreated. }@end


Add OAM functionality:
This document assumes you have already followed the Oracle Documentation and configured the Mobile and Social component of OAM)
Download the iOS SDK (oamms_sdk_for_ios.zip) from OTN website, extract the files and drag & drop the library file and the folders containing headers (libIDMMobileSDK.a, PublicHeaders and PublicResources) into the Xcode project.
Click on the project name to see the project properties and under general scroll down to Linked Frameworks and Libraries. Add the following libraries:


Security.Framework
SystemConfiguration.Framework
CoreLocation.Framework
Click on the “Build Settings” and scroll down to Linking. For the setting “Other Linker Flags” add: -ObjC “-all_load” (without the double quotes of course).
Add a new header file called constants.h to hold our OAM related constants:
constants.h:
#ifndef OAMLogin_constants_h#define OAMLogin_constants_h #define NUM_AUTH_RETRIES        3 #define OIC_URL @"http://oracle-access-server.company.com:14100" //your OIC REST URL#define OIC_SERVICE_DOMAIN  @"MobileServiceDomain"   //Defined during M&S configuration#define OIC_APP_NAME        @"OAMAuthTest"           //Defined during M&S configuration #endif


Modify the oamViewController h and m files as follows to implement OAM authentication.
oamViewController.h
#import
#import "IDMMobileSDK.h" @interface oamViewController : UIViewController
{            bool isAuthenticated;    OMMobileSecurityService *_mobileServices;    NSString *username;} @property (strong, nonatomic) IBOutlet UILabel *welcomeLabel;@property (strong, nonatomic) IBOutlet UIButton *authenticatedSegue;@property (nonatomic,assign) bool isAuthenticated;@property (nonatomic,retain) OMMobileSecurityService *mobileServices;
@end

 oamViewController.m
#import "oamViewController.h"  
#import "constants.h"
@interface oamViewController ()@end @implementation oamViewController @synthesize isAuthenticated; - (void)viewDidLoad{    [super viewDidLoad];    [self connectToOICServerAndSetup];    if(!isAuthenticated)    {        self.navigationItem.prompt = nil;        UIBarButtonItem *rightButton = [[UIBarButtonItem alloc]                                        initWithTitle:@"Login"                                        style:UIBarButtonItemStyleBordered                                        target:self                                        action:@selector(doLogin:)];        [self.navigationItem setRightBarButtonItem:rightButton                                          animated:YES];        self.authenticatedSegue.hidden = YES;    }    else    {        self.navigationItem.prompt = nil;        UIBarButtonItem *rightButton = [[UIBarButtonItem alloc]                                        initWithTitle:@"Logout"                                        style:UIBarButtonItemStyleBordered                                        target:self                                        action:@selector(doLogout:)];        [self.navigationItem setRightBarButtonItem:rightButton                                          animated:YES];        self.authenticatedSegue.hidden = NO;    }} - (IBAction)doLogin:(id)object{    [self doLogin];} - (void) doLogin{    if (self.mobileServices.applicationProfile == nil)    {        UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"Error"                                                            message:@"OAM server settings is not available."                                                           delegate:nil                                                  cancelButtonTitle:@"OK"                                                  otherButtonTitles:nil];        [alertView show];        [self performSegueWithIdentifier:@"ShowError" sender:self];        return;    }    NSError *error = nil;    error = [self.mobileServices startAuthenticationProcess:nil                                    presenterViewController:self]; } - (IBAction)doLogout:(id)object{    OMAuthenticationContext *ac = [self.mobileServices authenticationContext:TRUE];    if (ac != nil)    {        [self.mobileServices logout:FALSE];    }  
    [self didFinishLogout];} - (void)didFinishLogout{      isAuthenticated = NO;      self.navigationItem.prompt = nil;    UIBarButtonItem *rightButton = [[UIBarButtonItem alloc]                                    initWithTitle:@"Login"                                    style:UIBarButtonItemStyleBordered                                    target:self                                    action:@selector(doLogin:)];      [self.navigationItem setRightBarButtonItem:rightButton                                      animated:YES];    [self.welcomeLabel setText:[NSString stringWithFormat:@"Welcome Guest"]];    self.authenticatedSegue.hidden = YES;} - (void)didReceiveMemoryWarning{    [super didReceiveMemoryWarning];}  //OAM Related Stuff- (void)connectToOICServerAndSetup{    self.mobileServices = nil;  
    NSMutableDictionary *sdkProps = [[NSMutableDictionary alloc] init];    [sdkProps setObject:OM_PROP_AUTHSERVER_OAMMS forKey:OM_PROP_AUTHSERVER_TYPE];    [sdkProps setObject:OIC_URL forKey:OM_PROP_OAMMS_URL];    [sdkProps setObject:OIC_APP_NAME forKey:OM_PROP_APPNAME];    [sdkProps setObject:OIC_SERVICE_DOMAIN forKey:OM_PROP_OAMMS_SERVICE_DOMAIN];  
    OMMobileSecurityService *mss = [[OMMobileSecurityService alloc]                                    initWithProperties:sdkProps                                    delegate:self];    self.mobileServices = mss;  
    UIActivityIndicatorView *av = [[UIActivityIndicatorView alloc]                                   initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhite];    UIBarButtonItem *rightButton = [[UIBarButtonItem alloc] initWithCustomView:av];    [self.navigationItem setRightBarButtonItem:rightButton];    [av startAnimating];    [self.mobileServices setup];} - (void)didReceiveApplicationProfile:(NSDictionary *)applicationProfile                               error:(NSError *)error{    NSLog(@"Downloaded application profile: %@", applicationProfile);    if (error)    {        NSString *msg = [[NSString alloc] initWithFormat:@"%@-%d: %@",                         [error domain], [error code],                         [error localizedDescription]];        UIAlertView* alertView = [[UIAlertView alloc] initWithTitle:@"Application Initialization Failed"                                                            message:msg                                                           delegate:self                                                  cancelButtonTitle:@"OK"                                                  otherButtonTitles:nil];        [alertView show];        [self performSegueWithIdentifier:@"ShowError" sender:self];    }    UIBarButtonItem *rightButton = [[UIBarButtonItem alloc]                                    initWithTitle:@"Login"                                    style:UIBarButtonItemStyleBordered                                    target:self                                    action:@selector(doLogin:)];      [self.navigationItem setRightBarButtonItem:rightButton                                      animated:YES];} - (void)didFinishAuthentication:(OMAuthenticationContext *)context                          error:(NSError *)error{    NSLog(@"Got Authenticated: %d: %@",error.code, error.description);    if (context == nil || error != nil)    {        NSString *msg = [[NSString alloc] initWithFormat:@"%@-%d: %@", [error domain],                         [error code], [error localizedDescription]];        UIAlertView* alertView = [[UIAlertView alloc] initWithTitle:@"Authentication Status"                                                            message:msg                                                           delegate:self                                                  cancelButtonTitle:@"OK"                                                  otherButtonTitles:nil];        [alertView show];        return;    }  
    username = context.userName;    UIAlertView* alertView = [[UIAlertView alloc] initWithTitle:@"Successfully Authenticated!"                                                        message:[NSString stringWithFormat:@"Username: %@", username]                                                       delegate:self                                              cancelButtonTitle:@"OK"                                              otherButtonTitles:nil];    [alertView show];    isAuthenticated =YES;    self.navigationItem.prompt = nil;    UIBarButtonItem *rightButton = [[UIBarButtonItem alloc]                                    initWithTitle:@"Logout"                                    style:UIBarButtonItemStyleBordered                                    target:self                                    action:@selector(doLogout:)];    [self.navigationItem setRightBarButtonItem:rightButton                                      animated:YES];    self.authenticatedSegue.hidden = NO;    [self.welcomeLabel setText:[NSString stringWithFormat:@"Welcome %@", username]];  
} @end 
That’s it. This little app demonstrates just the authentication feature of OAM Mobile and Social iOS SDK. This can be used as a starter app for building your corporate iOS app. In the next article I will show how to make calls to REST API services protected my OAM 11g webgate using the SDK.

Sunday, August 24, 2014

Web APIs and API Management


It's a world of APIs. In the beginning only the big technology firms like Google, Twitter that catered to large developer community and mobile apps needed to expose APIs. But now, there can pretty much be no business with out APIs exposed to the outside. There are many reasons a business would want to expose APIs mobile apps being one of the foremost reason. Businesses would want make it easy for their partners, customers, vendors etc. by automating data exchange or transactions. With the advent of IOT APIs are going to become ever more important (machine to machine interaction).

Building RESTful APIs has become extremely easy with most technologies providing inherent frameworks. With ASP.NET Web API .NET developers can convert their old web services or applications into RESTful API in  matter of days if not hours. Similarly Jersey and Restlet among others make it easy to develop WebAPIs in Java. Modern languages such as Ruby on Rails and NodeJS are of course meant to be modern and cater towards WebAPIs and web application development. There are several books on RESTful API design which I believe is very important for technical leads and architects to refer to before building APIs for their organization.

The next step after designing and building the APIs is the API management functionality. We need the ability to manage the developers, monitor and track their activities and control their access. While this functionality can build in house or use of the several API management solution companies. There are many different "types" of providers in this space. One of the popular type of API management is the cloud hosted API gateways. Others types are on-premise software, on-premise appliance. The one I like and implemented is a plug-in or agent based solution which makes it a hybrid on-premise/cloud architecture.

Cloud Solution: Major vendors such as Layer 7, Apigee, Mashery etc. all offer cloud deployment solutions. In this model the cloud API gateway acts as a proxy to the APIs in your data center. API Management aspects such as developer on-boarding, key management, throttling, billing (if you are going to charge for your APIs) are all handled by the solution provider in the cloud. APIs may still stay in your data center. The provider makes the call to the API on behalf of the requests coming from developer applications. Some of the advantages of cloud solutions are easy setup and fast time to market. Some concerns are security and network latency.

On-Premise Solution: Again several of the major vendors also provide an on-premise solution. In this case vendor provides software or an appliance that you need to setup in your data center. The software or appliance will act as a proxy to the underlying WebAPIs. Some advantages are internal only situations, security and network latency. Some disadvantages are additional burden on IT to support hardware/software and cost.

Hybrid Plug-in solution: In this model the requests are made directly to the APIs. A plugin or agent intercepts the calls and checks with cloud based API management application (through API calls of course) before servicing the request. This solution provides ultimate flexibility and takes care of both internal and external situations. In addition to being a low cost solution, since this is a plug in model it is easy to replace if ever needed to replace with a different solution. 3Scale provides this kind of solution. There may be other vendors (Mashery?) providing similar solution, but I am not familiar.

Who are the players in API Management

There were not many players in this space only a couple of years ago. Now it seems like every technology company is a player in this space! Here is a small list:
Apigee
Layer 7
Mashery
3Scale
Oracle
Microsoft
IBM
MuleSoft

Open Source software:
WSO2
ApiAxle
API-Umbrella


Tuesday, March 25, 2014

Startup Shutdown scripts for WebLogic on Windows

It's a serious pain in the neck to setup WebLogic (11g at the moment) to automatically stop and start along with the system startup/Shutdown. Oracle should seriously consider doing something about it. Ideally install as Windows Service as soon as a domain is configured. However until that happens we are on our own.

I search around the web if someone had created an ideal solution already a script/document that I could follow and get this going in matter of minutes but alas I couldn't find a complete solution. I found bits and pieces here and there. So I took them and tailored them to write this blog. So here are the steps (this document assumes you have already configured node manager as a service and it is running)


1. Make sure Node Manager credentials are set correctly in WebLogic Admin Console

Go to the WebLogic console in Domain Structure, click on Domain Name - top level (e.g. oam_domain), click on Security tab and under General sub-tab click Advanced. Set the Node Manger credentials here (e.g. weblogic / Password123)

2. Add those credentials are put in nm_password.properties

Find (or create) the nm_password.properties file under \user_projects\domains\\config\nodemanager (e.g. - D:\Oracle\Middleware\user_projects\domains\oam_domain\config\nodemanager). Add the Node Manager credentials to the file. e.g.-

username=weblogic
password=Password123

3. Create boot.properties for the Administration Server


Follow these steps to create the boot.properties file:

Go to \user_projects\domains\\servers\AdminServer\security directory. e.g.-

D:\Oracle\Middleware\user_projects\domains\oam_domain/servers/AdminServer/security/

Use a text editor to create a file called boot.properties under the security directory. Enter the admin credentials. e.g-

username=weblogic
password=Password123

4. The scripts

A. weblogic.properties - Properties file used by scripts:

DOMAIN_NAME=oam_domain
MW_HOME=D:\\Oracle\\Middleware
DOMAIN_HOME=D:\\Oracle\\Middleware\\user_projects\\domains\\oam_domain
WEBLOGIC_USER=weblogic
WEBLOGIC_PASSWORD=Password123
HOST=myweblogicserver.company.com
NODEMANAGER_PORT=5556
ADMINSERVER_NAME=AdminServer
ADMINSERVER_PORT=7001
ADMINSERVER_URL=t3://myweblogicserver.company.com7001
MANAGEDSERVERS=oam_server,oim_server

B. startAdminServer.py - Starts the Admin Server

from java.io import FileInputStream
import java.lang
import os
import string
import datetime

logfile = "startManagedServer.log"
LOGFILE = open(logfile,"a")
now = datetime.datetime.now()
LOGFILE.writelines("Starting Admin Server - " + str(now) + "\n")

propInputStream = FileInputStream("weblogic.properties")
configProps = Properties()
configProps.load(propInputStream)

WEBLOGIC_USER = configProps.get("WEBLOGIC_USER")
WEBLOGIC_PASSWORD = configProps.get("WEBLOGIC_PASSWORD")
HOST = configProps.get("HOST")
NODEMANAGER_PORT = configProps.get("NODEMANAGER_PORT")
DOMAIN_NAME = configProps.get("DOMAIN_NAME")
DOMAIN_HOME = configProps.get("DOMAIN_HOME")
ADMINSERVER_NAME = configProps.get("ADMINSERVER_NAME")
ADMINSERVER_URL = configProps.get("ADMINSERVER_URL")

nmConnect(WEBLOGIC_USER, WEBLOGIC_PASSWORD, HOST, NODEMANAGER_PORT, DOMAIN_NAME, DOMAIN_HOME)
LOGFILE.writelines("Connected to NODE MANAGER Successfully...!!!" + "\n")
print ''
print '============================================='
print 'Connected to NODE MANAGER Successfully...!!!'
print '============================================='
print ''

print '###### ADMINSERVER NAME = ', ADMINSERVER_NAME
nmStart(ADMINSERVER_NAME)
LOGFILE.writelines("Successfully started " + ADMINSERVER_NAME + "\n\n")
print ''
print '============================================='
print '===> Successfully started ', ADMINSERVER_NAME, '  <==='
print '============================================='
print ''

C. stopAdminServer.py - Stops the Admin Server

from java.io import FileInputStream
import java.lang
import os
import string
import datetime

logfile = "stopAdminServer.log"
LOGFILE = open(logfile,"a")
now = datetime.datetime.now()
LOGFILE.writelines("Stopping Admin Server - " + str(now) + "\n")

propInputStream = FileInputStream("weblogic.properties")
configProps = Properties()
configProps.load(propInputStream)

WEBLOGIC_USER = configProps.get("WEBLOGIC_USER")
WEBLOGIC_PASSWORD = configProps.get("WEBLOGIC_PASSWORD")
HOST = configProps.get("HOST")
NODEMANAGER_PORT = configProps.get("NODEMANAGER_PORT")
DOMAIN_NAME = configProps.get("DOMAIN_NAME")
DOMAIN_HOME = configProps.get("DOMAIN_HOME")
ADMINSERVER_NAME = configProps.get("ADMINSERVER_NAME")
ADMINSERVER_URL = configProps.get("ADMINSERVER_URL")

connect(WEBLOGIC_USER, WEBLOGIC_PASSWORD, ADMINSERVER_URL) 
LOGFILE.writelines("Connected to Admin Server Successfully...!!!" + "\n")
print ''
print '============================================='
print 'Connected to Admin Server Successfully...!!!'
print '============================================='
print ''

print '###### ADMINSERVER NAME = ', ADMINSERVER_NAME
shutdown(force='true')
now = datetime.datetime.now()
LOGFILE.writelines("Successfully stopped " + ADMINSERVER_NAME + " " + str(now) + "\n\n")
print ''
print '============================================='
print '===> Successfully stopped ', ADMINSERVER_NAME, '  <==='
print '============================================='
print ''

LOGFILE.close()

D. startManagedServers.py - Starts all the Managed Servers (comma separated list in properties file)

from java.io import FileInputStream
import java.lang
import os
import string
import datetime

logfile = "startManagedServer.log"
LOGFILE = open(logfile,"a")
now = datetime.datetime.now()
LOGFILE.writelines("Starting Managed Server - " + str(now) + "\n")

propInputStream = FileInputStream("weblogic.properties")
configProps = Properties()
configProps.load(propInputStream)

WEBLOGIC_USER = configProps.get("WEBLOGIC_USER")
WEBLOGIC_PASSWORD = configProps.get("WEBLOGIC_PASSWORD")
HOST = configProps.get("HOST")
NODEMANAGER_PORT = configProps.get("NODEMANAGER_PORT")
DOMAIN_NAME = configProps.get("DOMAIN_NAME")
DOMAIN_HOME = configProps.get("DOMAIN_HOME")
ADMINSERVER_NAME = configProps.get("ADMINSERVER_NAME")
ADMINSERVER_URL = configProps.get("ADMINSERVER_URL")
MANAGEDSERVERS = configProps.get("MANAGEDSERVERS")

while True:
try:
print 'Trying to connect to AdminServer...'
connect(WEBLOGIC_USER, WEBLOGIC_PASSWORD, ADMINSERVER_URL) 
break
except:
print 'Could not connect to Admin Server. Sleeping for 30 seconds...'
sleep(30)

LOGFILE.writelines("Connected to Admin Server Successfully...!!!" + "\n\n")
print ''
print '============================================='
print 'Connected to Admin Server Successfully...!!!'
print '============================================='
print ''

MANAGEDSERVERLIST = MANAGEDSERVERS.split(',')
for MANAGEDSERVER in MANAGEDSERVERLIST:
print 'Starting managed server...'
print '###### MANAGEDSERVER = ', MANAGEDSERVER
start(MANAGEDSERVER, "Server", ADMINSERVER_URL, block="true")
LOGFILE.writelines("Successfully Started " + MANAGEDSERVER + "\n")
print ''
print '============================================='
print '===> Successfully started ', MANAGEDSERVER, '  <==='
print '============================================='
print ''

E. stopManagedServers.py - Stops all the Managed Servers (comma separated list in properties file)

from java.io import FileInputStream
import java.lang
import os
import string
import datetime

logfile = "stopManagedServer.log"
LOGFILE = open(logfile,"a")
now = datetime.datetime.now()
LOGFILE.writelines("Stopping Managed Server - " + str(now) + "\n")

propInputStream = FileInputStream("weblogic.properties")
configProps = Properties()
configProps.load(propInputStream)

WEBLOGIC_USER = configProps.get("WEBLOGIC_USER")
WEBLOGIC_PASSWORD = configProps.get("WEBLOGIC_PASSWORD")
HOST = configProps.get("HOST")
NODEMANAGER_PORT = configProps.get("NODEMANAGER_PORT")
DOMAIN_NAME = configProps.get("DOMAIN_NAME")
DOMAIN_HOME = configProps.get("DOMAIN_HOME")
ADMINSERVER_NAME = configProps.get("ADMINSERVER_NAME")
ADMINSERVER_URL = configProps.get("ADMINSERVER_URL")
MANAGEDSERVERS = configProps.get("MANAGEDSERVERS")

while True:
try:
print 'Trying to connect to AdminServer...'
connect(WEBLOGIC_USER, WEBLOGIC_PASSWORD, ADMINSERVER_URL) 
break
except:
print 'Could not connect to Admin Server. Sleeping for 30 seconds...'
sleep(30)

LOGFILE.writelines("Connected to Admin Server Successfully...!!!" + "\n")
print ''
print '============================================='
print 'Connected to Admin Server Successfully...!!!'
print '============================================='
print ''

MANAGEDSERVERLIST = MANAGEDSERVERS.split(',')
for MANAGEDSERVER in MANAGEDSERVERLIST:
print 'Stopping managed server...'
print '###### MANAGEDSERVER = ', MANAGEDSERVER
shutdown(MANAGEDSERVER, "Server", ADMINSERVER_URL, force="true", block="true")
LOGFILE.writelines("Successfully stopped " + MANAGEDSERVER + "\n\n")
print ''
print '============================================='
print '===> Successfully stopped ', MANAGEDSERVER, '  <==='
print '============================================='
print ''

F. startup.bat - Batch file to start all servers sequentially

startAdminServer.bat && startManagedServer.bat

G. shutdown.bat - Batch file to stop all servers sequentially

stopManagedServer.bat & stopAdminServer.bat

5. Add scripts to system start-up / shutdown

Follow the steps provided here: http://technet.microsoft.com/en-us/library/cc770556.aspx to add startup.bat and shutdown.bat to the system startup and shutdown.

Thursday, December 22, 2011

SharePoint 2010 OAM Integration

This document outlines steps involved in Integrating SharePoint 2010 with OAM 10g.

Prerequisites:

  • SharePoint 2010 is installed and configured. You are able to create web applications and site collections.
  • OAM environment is installed and configured (Access Servers, Identity Servers etc).
  • Access Gate is configured for the webgate for webgate installation
  • A Policy Domain is configured for this resource (SharePoint 2010 URL).
  • Following Return Attributes are setup for Authorization Success in the Authorization Expression:

HeaderVar IMPERSONATE uid (or samaccountname)
HeaderVar SP_SSO_UID uid (or samaccountname)
COOKIE OAMAuthCookie uid (or samaccountname)
Assumptions

  • Web Application main site will be created using port 8081 (Claims based Authentication, NTLM only)
  • Main web application will be extended to Internet zone using port 80 and Forms based authentication only. Use CustomLDAPMembershipProvider and CustomRoleProvider for providers.


Step 1
In web.config of Central Admin (C:\inetpub\wwwroot\wss\VirtualDirectories\24195\web.config [on your server the folder name maybe different]) - Don't forget to make a backup first.

REPLACE
<roleManager><providers></providers></roleManager><membership><providers></providers></membership>
WITH
<roleManager><providers><addname="CustomRoleProvider" type="Microsoft.Office.Server.Security.LdapRoleProvider, Microsoft.Office.Server, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71E9BCE111E9429C"server="[LDAP Server name]"port="389"useSSL="false"groupContainer=" dc=[Company],dc=com"groupNameAttribute="cn"groupMemberAttribute="uniquemember"userNameAttribute="uid"groupFilter="(ObjectClass=groupOfUniqueNames)"userFilter="(ObjectClass=inetorgperson)"scope="Subtree" /></providers></roleManager><membership><providers><addname="CustomLDAPMembershipProvider" type="Microsoft.Office.Server.Security.LDAPMembershipProvider, Microsoft.Office.Server, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71E9BCE111E9429C"server="[LDAP Server Name]"port="389"useSSL="false"useDNAttribute="false"userNameAttribute="uid"userContainer="dc=[company],dc=com"userFilter="(objectClass=person)"scope="Subtree" otherRequiredUserAttributes="sn,givenname,cn" /></providers></membership>
Step 2
Deploy OAMCustomMembershipProvider.dll to GAC
(C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bin\gacutil.exe - This could be different on your server)

gacutil -I D:\OAM\access\oblix\apps\webgate\OAMCustomMembershipProvider\OAMCustomMembershipProvider.dll

Alternatively drag and drop the OAMCustomMembershipProvider.dll to c:\windows\assembly

Step 3
In web.config of SecurityTokenServiceApplication Application (Application under SharePoint Web Services Site)
C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\14\WebServices\SecurityToken\web.config
Don't forget to make a backup first.

Add the below block right under </system.net>:
<system.web>
<membership>
<providers>
<add
name="CustomLDAPMembershipProvider" type="Oracle.CustomMembershipProvider, OAMCustomMembershipProvider,Version=1.0.0.0, Culture=neutral, PublicKeyToken=52e6b93f6f0427a1, processorArchitecture=AMD64"
server="[LDAP Server Name]"
port="389"
useSSL="false"
useDNAttribute="false"
userNameAttribute="uid"
userContainer="dc=[company],dc=com"
userFilter="(objectClass=person)"
scope="Subtree" otherRequiredUserAttributes="sn,givenname,cn" ValidationURL=http://[YourServerName]/ValidateCookie.html
DebugFile="D:\OAM\Logs\debug.log"
OAMAuthUser="OAMAuthCookie"/>
</providers>
</membership>
<roleManager enabled="true">
<providers>
<add
name="CustomRoleProvider" type="Microsoft.Office.Server.Security.LdapRoleProvider, Microsoft.Office.Server, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71E9BCE111E9429C"
server="[LDAP Server Name]"
port="389"
useSSL="false"
groupContainer="cn=groups,dc=<Company>,dc=com"
groupNameAttribute="cn"
groupMemberAttribute="uniquemember"
userNameAttribute="uid"
groupFilter="(ObjectClass=groupOfUniqueNames)"
userFilter="(ObjectClass=inetorgperson)"
scope="Subtree" />
</providers>
</roleManager>
</system.web>

Make sure the validation URL works (http://[YourServerName]/ValidateCookie.html) on your server. Put a ValidationCookie.html file in the root of "80" site with anything in it (Hello is ok). Make sure D:\OAM\Logs folder exists.

If there are issues with OAM integration this line under <behavior name="SecurityTokenServiceBehavior"> would help with debugging:
<serviceDebug includeExceptionDetailInFaults="true"/>

Step 4
In the web.config of "80" site (D:\inetpub\wwwroot\wss\VirtualDirectories\80) - Don't forget to make a backup first.

Add the following lines under <providers> for <membership> node

<add name="CustomLDAPMembershipProvider"
type="Microsoft.Office.Server.Security.LDAPMembershipProvider, Microsoft.Office.Server, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71E9BCE111E9429C"
server="[LDAP Server Name]"
port="389" useSSL="false" useDNAttribute="false" userNameAttribute="uid"
userContainer="dc=[company],dc=com" userFilter="(objectClass=person)"
scope="Subtree" otherRequiredUserAttributes="sn,givenname,cn" />

Add the following lines under <providers> for <roleManager> node
<add name="CustomRoleProvider"
type="Microsoft.Office.Server.Security.LdapRoleProvider, Microsoft.Office.Server, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71E9BCE111E9429C"
server="[LDAP Server Name]" port="389" useSSL="false" groupContainer=" dc=[company],dc=com"
groupNameAttribute="cn" groupMemberAttribute="uniquemember"
userNameAttribute="uid" groupFilter="(ObjectClass=groupOfUniqueNames)"
userFilter="(ObjectClass=inetorgperson)" scope="Subtree" />

Step 5
In the Default.aspx of the " 80" site (D:\inetpub\wwwroot\wss\VirtualDirectories\80\_forms\Default.aspx) - Don't forget to make a backup first.

Add the following lines just above </asp:Content>
<asp:HiddenField EnableViewState="false" ID="loginTracker" runat="server" value="autoLogin" />
<%bool autoLogin = loginTracker.Value == "autoLogin";%>
<script runat="server">
void Page_Load()
{
signInControl.LoginError += new EventHandler(OnLoginError);
NameValueCollection headers = Request.ServerVariables;
NameValueCollection queryString = Request.QueryString;
string loginasanotheruser = queryString.Get("loginasanotheruser");
string username = Request.ServerVariables.Get("HTTP_SP_SSO_UID");
HttpCookie ObSSOCookie = Request.Cookies["ObSSOCookie"];
bool isOAMCredsPresent = username != null && username.Length > 0 && ObSSOCookie != null && ObSSOCookie.Value != null;
bool signInAsDifferentUser = loginasanotheruser != null && loginasanotheruser.Contains("true");


if (isOAMCredsPresent)
{
//Handling For UTF-8 Encoding in HeaderName
if (username.StartsWith("=?UTF-8?B?") && username.EndsWith("?="))
{
username = username.Substring("=?UTF-8?B?".Length, username.Length - 12);
byte[] decodedBytes = Convert.FromBase64String(username);
username = Encoding.UTF8.GetString(decodedBytes);
}
}
if (isOAMCredsPresent && loginTracker.Value == "autoLogin" && !signInAsDifferentUser)
{
bool status=Microsoft.SharePoint.IdentityModel.SPClaimsUtility.AuthenticateFormsUser (new Uri(SPContext.Current.Site.Url),username,"ObSSOCookie:"+ObSSOCookie.Value);
if(status){
if (Context.Request.QueryString.Keys.Count > 1)
{
Response.Redirect(Context.Request.QueryString["Source"].ToString());
}
else
{
Response.Redirect(Context.Request.QueryString["ReturnUrl"].ToString());
}
}
else{
loginTracker.Value = "";
}
}
else
{
// DO NOTHING
}
}
void OnLoginError(object sender, EventArgs e)
{
loginTracker.Value = "";
}
</script>

Step 6
To disable Persistent cookie run the following powershell script:
Get-PSSnapin -RegisteredAdd-PSSnapin Microsoft.SharePoint.Powershell$sts = Get-SPSecurityTokenServiceConfig$sts.UseSessionCookies = $true$sts.Update()iisreset
Step 7
Go App management in Central admin. Click on the main web app (8081) and click on User Policy, Add yourself (from the FBA account) with Full Control.

Step 8
Add the webgate to "80" site in IIS Manager.

Step 9
Test the site by going to http://[yourserver]. You should be able to login as yourself and you should have full access. Give other LDAP users access in the next step.

Step 10
Go to http://[yourserver]/_layouts/user.aspx. Click on "Site Visitors", click on new, search for All and add "All Authenticated Users" and click Ok.

Now all users who can authenticate against OAM have read access to the site.