Decode SAML Authentication Request

Decode Authenticate Request :

samlsample


/*
* Retrieves the AuthnRequest from the encoded and compressed String extracted
* from the URL. The AuthnRequest XML is retrieved in the following order: <p>
* 1. URL decode <br> 2. Base64 decode <br> 3. Inflate <br> Returns the String
* format of the AuthnRequest XML.
*/
public static String decodeAuthnRequestXML(String encodedRequestXmlString)
throws SamlException {
try {
// URL decode
// No need to URL decode: auto decoded by request.getParameter() method

// Base64 decode
Base64 base64Decoder = new Base64();
byte[] xmlBytes = encodedRequestXmlString.getBytes("UTF-8");
byte[] base64DecodedByteArray = base64Decoder.decode(xmlBytes);

//Uncompress the AuthnRequest data
//First attempt to unzip the byte array according to DEFLATE (rfc 1951)
try {

Inflater inflater = new Inflater(true);
inflater.setInput(base64DecodedByteArray);
// since we are decompressing, it's impossible to know how much space we
// might need; hopefully this number is suitably big
byte[] xmlMessageBytes = new byte[5000];
int resultLength = inflater.inflate(xmlMessageBytes);

if (inflater.getRemaining()>0) {

System.out.println("Inflater Error :: didn't allocate enough space to hold decompressed data :: "+inflater.getRemaining());
throw new RuntimeException("didn't allocate enough space to hold "
+ "decompressed data");
}

inflater.end();
return new String(xmlMessageBytes, 0, resultLength, "UTF-8");

} catch (DataFormatException e) {

// if DEFLATE fails, then attempt to unzip the byte array according to
// zlib (rfc 1950)
ByteArrayInputStream bais = new ByteArrayInputStream(
base64DecodedByteArray);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
InflaterInputStream iis = new InflaterInputStream(bais);
byte[] buf = new byte[1024];
int count = iis.read(buf);
while (count != -1) {
baos.write(buf, 0, count);
count = iis.read(buf);
}
iis.close();
return new String(baos.toByteArray());
}

} catch (UnsupportedEncodingException e) {
throw new SamlException("Error decoding AuthnRequest: " +
"Check decoding scheme - " + e.getMessage());
} catch (IOException e) {
throw new SamlException("Error decoding AuthnRequest: " +
"Check decoding scheme - " + e.getMessage());
}
}

 

Advertisements

WebSphere Portal oAuth2 – GAE

I have come up with below architecture to read GAE appspot data with oAuth2.0
1.Create Service account and private key using Google API console
2.Create JWT (JSON Web Token) on the portal application which wants to access the data from GAE
3.Pass JWT Token as part of the headers to appspot
4.Validate JWT token from appspot and send the request information in JSON format.
gae-oauth2

Sample code to create JWT :

import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.InputStream;
import java.security.InvalidKeyException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.Signature;
import java.security.SignatureException;
import java.security.UnrecoverableKeyException;
import java.security.cert.CertificateException;
import java.util.ResourceBundle;

import org.apache.commons.codec.binary.Base64;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpException;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.methods.PostMethod;
import org.json.JSONException;
import org.json.JSONObject;
import com.google.gson.JsonParser;

/**
* Servlet implementation class GoogleServiceAccount
*/
public class GoogleServiceAccountOAuth {

static String keyAlias = "privatekey";
public ResourceBundle bundle = ResourceBundle
.getBundle("com.ibm.ereportscursors.nl.EReportsCursorsPortletResource");
public static byte[] signData(byte[] data, PrivateKey privateKey)
throws InvalidKeyException, SignatureException,
NoSuchAlgorithmException {
Signature signature = Signature.getInstance("SHA256withRSA");
signature.initSign(privateKey);
signature.update(data);
return signature.sign();
}

public static String encodeBase64(byte[] rawData) {
byte[] data = Base64.encodeBase64(rawData);
return data.toString();
}

private static PrivateKey getPrivateKey(InputStream fis, String password)
throws KeyStoreException, IOException, NoSuchAlgorithmException,
CertificateException, UnrecoverableKeyException {
KeyStore keystore = KeyStore.getInstance("PKCS12");
keystore.load(fis, password.toCharArray());
PrivateKey privateKey = (PrivateKey) keystore.getKey(keyAlias, password
.toCharArray());
return privateKey;
}

public String getAccessToken(String oAuth_EmailID) {
String token_str="";
String password = bundle.getString("Certificate_Pwd");
try {
String jwtHeaderStr = null;
String jwtClaimStr = null;
PrivateKey privateKey = null;

// JWT HEADER
JSONObject jwtHeader = new JSONObject();
try {
jwtHeader.put("alg", "RS256");
jwtHeader.put("typ", "JWT");
jwtHeaderStr = jwtHeader.toString();
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

byte[] encodedHeader = Base64.encodeBase64(jwtHeaderStr
.getBytes("UTF-8"));

// JWT CLAIMSET
JSONObject jwtClaimSet = new JSONObject();
long iat = (System.currentTimeMillis() / 1000) - 60;
long exp = iat + 3600;
try {
jwtClaimSet
.put("iss",
oAuth_EmailID);
jwtClaimSet.put("scope",
bundle.getString("OAuth_Scope"));

jwtClaimSet.put("aud",
bundle.getString("OAuth_Aud"));
jwtClaimSet.put("exp", +exp);
jwtClaimSet.put("iat", +iat);
jwtClaimStr = jwtClaimSet.toString();
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

byte[] encodedClaimSet = Base64.encodeBase64(jwtClaimStr
.getBytes("UTF-8"));

StringBuffer token = new StringBuffer();
token.append(new String(encodedHeader));
token.append(".");
token.append(new String(encodedClaimSet));

// JWT SIGNATURE
InputStream fis = this.getClass().getResourceAsStream(
"ereports_test1.p12");
privateKey = getPrivateKey(fis, password);
byte[] sig = signData(token.toString().getBytes("UTF-8"),
privateKey);
byte[] encodedSig = Base64.encodeBase64(sig);
System.out.println("Signature before encoding:"
+ new String(encodedSig));
String signedPayload = encodeBase64(sig);
// System.out.println("Signature before encoding:"+signedPayload);
token.append(".");
// token.append(signedPayload);
token.append(new String(encodedSig));

HttpClient client = new HttpClient();
PostMethod method = new PostMethod(
bundle.getString("OAuth_PostURL"));
method.addRequestHeader("Content-Type",
bundle.getString("OAuth_PostContentType"));
method.addParameter("grant_type",
bundle.getString("OAuth_Grant_Type"));
System.out.println("printing Token.toString():" + token.toString());
method.addParameter("assertion", token.toString());

try {
int responseCode = client.executeMethod(method);
System.out.println(responseCode);
String respop = method.getResponseBodyAsString();
System.out.println(method.getResponseBodyAsString());

JsonParser parser = new JsonParser();

token_str = parser.parse(respop).getAsJsonObject().get(
"access_token").getAsString();
} catch (HttpException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} catch (Exception e) {
e.printStackTrace();
}
return  token_str;

}

</div>
<div class="separator">

}

Oracle Datagaurd

We had to recently implement Oracle Datagaurd for websphere portal.

What is Oracle Datagaurd ?

Oracle Data Guard ensures high availability, data protection, and disaster recovery for enterprise data. Data Guard provides a comprehensive set of services that create, maintain, manage, and monitor one or more standby databases to enable production Oracle databases to survive disasters and data corruptions. Data Guard maintains these standby databases as transactionally consistent copies of the production database. Then, if the production database becomes unavailable because of a planned or an unplanned outage, Data Guard can switch any standby database to the production role, minimizing the downtime associated with the outage. Data Guard can be used with traditional backup, restoration, and cluster techniques to provide a high level of data protection and data availability.

Usually datagaurd URL which should be working is below in most of enterprise applications is below

jdbc:oracle:thin:@(DESCRIPTION =(ADDRESS_LIST =(ADDRESS=(PROTOCOL=tcp)(HOST=SERVER1)(PORT=1524))(ADDRESS=(PROTOCOL=tcp)(HOST=SERVER2)(PORT=1524)))(LOAD_BALANCE = no)(FAILOVER = yes)(CONNECT_DATA =(SERVICE_NAME = wpsprd)(SERVER = DEDICATED)(FAILOVER_MODE =(TYPE = select)(METHOD = BASIC)(RETRIES = 18000)(DELAY = 2))))

For some reason this does not work with websphere portal, as  a workaround we updated websphere portal server host file with an entry like below.

datagaurd  Database server1 IP
#datagaurd  Database server2 IP

Updated all JDBC URL’s replacing server name with datagaurd.

After updating the jdbc url, we need to run the following commands:

./ConfigEngine.sh validate-database-driver -DWasPassword=XXXXX

./ConfigEngine.sh validate-database-connection -DWasPassword=XXXXX

./ConfigEngine.sh connect-database -DWasPassword=XXXXX

Webseal LTPA Expiry Issue

One of the components of Tivoli Access Manager is its reverse proxy security server called WebSEAL. WebSEAL can front-end any Web application server or Web server in an enterprise e-business infrastructure. When WebSphere Application Server and WebSphere Portal are implemented with WebSEAL, it is usually necessary to provide a SSO experience for the end user. In order to achieve SSO, the WebSphere Application Server needs to be configured to “trust” the WebSEAL server so that if WebSEAL has already authenticated a user, Application Server will not challenge the user again.

 

pngbase6472e483fb6375d4f5

 

Request flow:
1. User requests a resource protected by WebSEAL. User is challenged by WebSEAL for credentials, and the user supplies them.
2. WebSEAL authenticates the user by communicating with its user registry. It also determines whether the user is authorized to open the requested URL. Upon successful authentication of the end user, WebSEAL creates the LTPA token cookie.
3. The request is passed to the IBM HTTP Server using the junction that is configured for it. The junction from WebSEAL to IBM HTTP Server is configured to pass the iv-user, iv-groups information, and the LTPA Token that was created in Step 2, in the HTTP header.
4. The request is forwarded to the appropriate WebSphere Application Server or clone, as determined by the Application Server plug-in.
5. In WebSphere Application Server, the TAI is not enabled and Application Server gets the LTPA token in the header. Application Server only creates the session cookie for this user and assumes that this user has been authenticated. WebSphere Portal searches LDAP for the group information, gets the resource mapping from the database, and then displays the portal page.
Issue:
Logging in to portal using webseal some times gives below error even after providing correct user id and password
Which means LTPA token for websphere portal on webseal expired.


Lets see how to export the keys from portal and import to webseal.


Step1 : login to portal console using wpadmin


click Security > Secure administration, applications and infrastructure and then click Authentication Mechanism and Expiration.


  1. In the Cross-cell single sign-on section, type a password and an absolute path for a key file.
  2. Click Export keys. The key file is generated.

 

Once the keys generated we need to update in webseal

 

Copy the keys to your local machine which will be imported to webseal servers later

 

Login to TAM
Go to Junctions and open /wps61dev (one which has problem in this case its dev portal)
Need to update below things
1.Update key file with new file we exported
     Copy the the key file to path /opt/pdweb/jct_keys
2.Update password , repeat the steps on other webseal server also
Click on apply on junction and then try to login to portal again and it should be successful now.

TAM API Setup for WebSphere Portal

Following are the installations and Configurations to be done for using TAM API

  1. Access Manager Runtime for Java
  2. pdjrtecfg utility to configure Access Manager runtime for java (utility gets installed with access manager runtime for Java)
  3. svrsslcfg to configure SSL connection to policy server.

————————Windows Setup———————————–

————————AIX Setup———————————–

Windows: Installing Access Manager Runtime for Java

The following procedure uses the setup.exe program to install the Access Manager Runtime for Java package and thepdjrtecfg utility to configure it.

To install and configure a Tivoli Access Manager Runtime for Java system on Windows® 2003, Windows Vista or Windows XP, follow these steps.

  1. Log on as a user with Administrator group privileges.
  2. Ensure that all necessary operating system patches are installed. Also ensure that you have reviewed the most-recent release information, including system requirements, disk space requirements, and known defects and limitations in theIBM Tivoli Access Manager for e-business: Release Notes or Technotes in the support knowledge database.
  3. Insert the IBM Tivoli Access Manager Base for Windows CD.
  4. Install the Tivoli Access Manager packages. To do so, run the setup.exe file, located in the following directory:

\windows\PolicyDirector\Disk Images\Disk1

Follow the online instructions and select to install the following packages:

    • Access Manager License
    • Access Manager Runtime for Java
  1. Ensure that either IBM® Java™ Runtime 1.5.0 SR5 provided with Tivoli Access Manager or the JRE provided with WebSphere® Application Server 6.1 is installed. For instructions on installing IBM Java Runtime 1.5.0 SR5, see pageWindows: Installing IBM Java Runtime.

Access Manager Runtime for Java configures additional security features into the specified JRE and only these two JREs are supported.

  1. To view status and messages in a language other than English, which is the default, install your language support packagebefore configuring packages. For instructions, see Installing language support packages for Tivoli Access Manager.
  2. To set up Access Manager Runtime for Java with a configuration type of Full, ensure that both the policy server and registry server are running. If the configuration type is standalone, this step is not required.
  3. To configure the Access Manager Runtime for Java component, change to the c:\Program Files\Tivoli\Policy Director\sbindirectory and enter the following:

PDJRTEcfg configuration

“c:\Program Files\Tivoli\Policy Director\sbin\pdjrtecfg.exe” -action config -host TORPDQ10 -port 9043 -java_home “C:\IBM\WebSphere\AppServer\java\jre”

Svrsslcfg Configuration

Go to C:\ibm\WebSphere\AppServer\java\jre\bin and run the below command

java com.tivoli.pd.jcfg.SvrSslCfg -action config -admin_id sec_master -admin_pwd celP0rta11 -appsvr_id PDPermissionjapp -appsvr_pwd password -host TORPDQ10 -mode remote -port 9043 -policysvr TORPDQ10:7135:1 -authzsvr TORPDQ10:7136:1 -cfg_file D:\IBM\WebSphere\AppServer\java\jre\PolicyDirector\PDPerm.properties -key_fileD:\IBM\WebSphere\AppServer\java\jre\PolicyDirector\pdperm.ks -domain Default -cfg_action create

AIX®: Installing Access Manager Runtime for Java

The following procedure uses installp to install Access Manager Runtime for Java and the pdjrtecfg utility to configure it.

  1. Log on as root.
  2. Ensure that all necessary operating system patches are installed. Also, ensure that you have reviewed the most-recent release information, including system requirements, disk space requirements, and known defects and limitations. See theIBM Tivoli Access Manager for e-business: Release Notesor Technotes in the support knowledge database.
  3. Insert the IBM Tivoli Access Manager Base for AIX CD and mount it.
  4. Install the Tivoli Access Manager packages:

5. installp -acgYXd cd_mount_point/usr/sys/inst.images packages

where cd_mount_point is the directory where the CD is mounted and packages are as follows:

PD.lic

Specifies the Access Manager License package.

PDJ.rte

Specifies the Access Manager Runtime for Java package.

  1. Ensure that either IBM® Java™ Runtime 1.5.0 SR5 provided with Tivoli Access Manager or the JRE provided with WebSphere® Application Server 6.1 is installed. For instructions on installing IBM Java Runtime 1.5.0 SR5, see page AIX: Installing IBM Java Runtime.

Access Manager Runtime for Java configures additional security features into the specified JRE and only these two JREs are supported.

  1. Unmount the CD.
  2. To view status and messages in a language other than English, which is the default, install your language support packagebefore configuring packages. For instructions, see Installing language support packages for Tivoli Access Manager.
  3. To set up a Tivoli Access Manager Runtime for Java system with a configuration type of Full, ensure that both the policy server and registry server are running. If the configuration type is standalone, this step is not required.
  4. Before configuring the Access Manager Runtime for Java component, ensure that either the IBM Java Runtime 1.5.0 SR5 provided with Tivoli Access Manager or the JRE provided with WebSphere Application Server 6.1 can be located using the PATH environment variable.
  5. To configure the Access Manager Runtime for Java component, change to the /opt/PolicyDirector/sbin directory and enter the following:

PDJRTEcfg configuration

./pdjrtecfg -host TORPDQ10 -port 9043 -java_home /IBM61/WebSphere/AppServer/java/jre

Svrsslcfg Configuration

Go to /IBM61/WebSphere/AppServer/java/jre/bin and run the below command

java com.tivoli.pd.jcfg.SvrSslCfg -action config -admin_id sec_master -admin_pwd celP0rta11 -appsvr_id PDPermissionjapp -appsvr_pwd password -host TORPDQ10 -mode remote -port 9043 -policysvr TORPDQ10:7135:1 -authzsvr TORPDQ10:7136:1 -cfg_file /IBM61/WebSphere/AppServer/java/jre/PolicyDirector\PDPerm.properties -key_file/IBM61/WebSphere/AppServer/java/jre/PolicyDirector\pdperm.ks -domain Default -cfg_action create