Monthly Archive: October 2009

Configuring SAML 1.0 in a Clustered Weblogic Server

In this document, we will discuss the configurations required on the Weblogic Server 10.3 source site and destination site for SAML 1.0.

Architecture

On a single machine we have Apache Web server, IIS Web server and 2 Weblogic Server Domains. We have two servers on one domain hosting the source application and two servers on the second domain hosting the destination application.

The servers on the source site are listening on port 7001 and 7003 over HTTP, and the servers on the destination domain are listening on port 7003 and 7005 over HTTP. Apache Web Server proxies the source site and is listening on port 8080 and IIS Web Server proxies the destination site and is listening on port 8090.

Follow the Steps below to configure SAML 1.0 in a Weblogic Cluster.

Configure Apache Plug-in with Weblogic Server

1. Make sure the Apache server runs & serves on port 8080.
This can be done by modifying the httpd.conf present at
D:\Program Files\Apache Group\Apache2\conf
Modify the Listen port to 8080

Listen 8080

2. Copy the mod_wl_20.so from <bea_home>\wlserver_10.3\server\plugin\win\32 to
D:\Program Files\Apache Group\Apache2\modules

3. Apply the plug-n module by adding these in the httpd.conf file

LoadModule weblogic_module modules/mod_wl_20.so

<Location />
SetHandler weblogic-handler
</Location>

<IfModule mod_weblogic.c>
WebLogicCluster
Debug ON
WLLogFile c:/temp/wlproxy.log
WLTempDir c:/temp
</IfModule>

4. Restart the Apache Server.

Configure IIS Plug-in with Weblogic Server

1. Make a directory on the IIS box for the plug-in.
For instance: c:\Inetpub\WLS_IIS_Plugin\

2. Copy iisforward.dll and iisproxy.dll to this new directory.
These files are located at:
10.0: <bea_home>\wlserver_10.0\server\plugin\win\32
10.3: <bea_home>\wlserver_10.3\server\plugin\win\32

3. To install iisforward.dll as an ISAPI filter, do the following:
Go to Start->Administrative Tools->Internet Information Services
(IIS) Manager
In the left pane, drill down to the active website
(like “Default Web Site”)
Right-click the active website and select Properties
Select the ISAPI Filters tab and press the Add button
Filter name: WLS IIS Plugin
Or whatever you want
Executable: C:\Inetpub\WLS_IIS_Plugin\iisforward.dll
Or whatever path you created
Press OK twice
IIS6 does not allow the iisforward.dll ISAPI Extension to run by default.

To enable:
In the left pane of the Internet Information Services (IIS) Manager,
click on Web Service Extension (located under the computer name)
In the right pane, highlight All Unknown ISAPI Extensions and press
the Allow button

4. To map .wlforward to use iisproxy.dll, do the following:
a. In the left pane, drill down to the active website (like
“Default Web Site”)
b. Right-click the active website and select Properties
c. Select Home Directory tab
d. Click the Configuration… button.
e. In the Application Mapping tab, click the Add… button.
a. Executable: C:\Inetpub\WLS_IIS_Plugin\iisproxy.dll
b. Extension: .wlforward
f. Uncheck Verify that file exists
g. IMPORTANT: Ensure .wlforward is *not* mapped to iisforward.dll.
While this seems intuitive, it is wrong. .wlforward maps to
iisproxy.dll.
h. Press OK three times
i. Exit the IIS Manager MMC console.

5. Create a text file named iisproxy.ini and place it in the plug-in
directory (e.g. c:\Inetpub\WLS_IIS_Plugin\iisproxy.ini)

iisproxy.ini

WebLogicCluster=localhost:7001,localhost:7003
WlForwardPath=/
Debug=ALL
DebugConfigInfo=ON
WLLogFile=c:/temp/iisproxy.log

6. Restart IIS using the following CLI statement: iisreset /restart

7. Use a browser to access IIS. This will ‘turn on’ the IIS->WLS
ISAPI filter.

8. Relaunch the IIS Manager and check the ISAPI filter tab to ensure
the iisforward.dll is now ‘turned on’, as evidenced by a green arrow.

Generate Key to sign the assertion:

keytool -genkey -keypass password -keystore DemoIdentity.jks -keyalg rsa -alias faisal_key –storepass DemoIndentityKeyStorePassPhrase

What is your first and last name?
[Unknown]: Faisal
What is the name of your organizational unit?
[Unknown]: BEA
What is the name of your organization?
[Unknown]: Oracle
What is the name of your City or Locality?
[Unknown]: Pune
What is the name of your State or Province?
[Unknown]: MH
What is the two-letter country code for this unit?
[Unknown]: IN
Is CN=Faisal, OU=BEA, O=Oracle, L=Pune, ST=MH, C=IN correct?
[no]: y

Export the certificate:

keytool -export -alias faisal_key -keystore DemoIdentity.jks -file faisal.der -storepass DemoIdentityKeyStorePassPhrase
Certificate stored in file <faisal.der>

SOURCE SITE CONFIGURATION (SamlSource)

Security Realms > myrealm > Providers > Credential Mapping
Add a SAML credential mapped V2.

Issuer URI http://www.samlserver.com/samlTraining
Name Qualifier support.samlserver.com
Signing Key Alias faisal_key
Signing Key Pass Phrase password
Confirm Signing Key Pass password

Restart the server

Security Realms > myrealm > Providers > Credential Mapping >
SAMLCredentialMapper > Management and create new Relying Parties and select
“Browser/POST” profile from dropdown menu.

Enabled checkbox (true)
Target URL http://localhost:8090/samldest01App
/restricted01/samldest01services.jsp
Assertion Consumer URL http://localhost:8090/samlacs/acs
Assertion Consumer Parameters APID=ap_00001
Sign Assertions checkbox (true)
Include Keyinfo checkbox (true)
Include Groups Attribute checkbox (true)

Servers > Server1 > Federation Services > SAML 1.1 Source Site

Source Site Enabled checkbox (true)
Source Site URL http://localhost:8080/samlsourceApp
Signing Key Alias faisal_key
Signing Key Passphrase password
Intersite Transfer URIS /samlits_cc/its
(Keep the other values)
ITS Requires SSL checkbox (false)
Assertion Retrieval URIs /samlars/ars
ARS Requires SSL checkbox (true)

Servers > Server2 > Federation Services > SAML 1.1 Source Site

Source Site Enabled checkbox (true)
Source Site URL http://localhost:8080/samlsourceApp
Signing Key Alias faisal_key
Signing Key Passphrase password
Intersite Transfer URIS /samlits_cc/its
(Keep the other values)
ITS Requires SSL checkbox (false)
Assertion Retrieval URIs /samlars/ars
ARS Requires SSL checkbox (false)

DESTINATION SITE CONFIGURATION (SamlDestination)

Security Realms > myrealm > Providers > Authentication> Create a New Authentication Provider > Select SAMLIdentityAsserterV2

Restart the server

Go to “Security Realms > myrealm > Providers > Authentication” Click on newly created SAMLIdentityAsserter’s “Management > Certificates tab and configure the signing certificate

Alias faisal_key
Certificate File Name faisal.der

Go to the newly created SAML Identity Asserter‘s “Management > Asserting Party tab and press new button to create new SAML asserting party and select “Browser/POST” profile from dropdown menu.

Enabled checkbox (true)
Target URL http://localhost:8080/samlsourceApp
POST Signing Certificate alias faisal_key
Source Site Redirect URIs /samldest01App/restricted01/
samldest01services.jsp
Source Site ITS URL http://localhost:8080/samlits_ba/its
Source Site ITS Parameters RPID=rp_00001
Issuer URI http://www.samlserver.com/samlTraining
Signature Required checkbox (true)
Asserting Signing Certificate Alias faisal_key
Process Groups Attribute checkbox (true)

Servers > Server3> Federation Services > SAML 1.1 Destination Site

Destination Site Enabled checkbox (true)
Assertion Consumer URIs /samlacs/acs
ACS Requires SSL checkbox (false)
SSL Client Identity Alias faisal_key
SSL Client Identity Pass Phrase password
POST Recipient Check Enabled checkbox (true)
POST one Use Check Enabled checkbox (true)
Used Assertion Cache Properties APID=ap_00001

Servers > Server4> Federation Services > SAML 1.1 Destination Site

Destination Site Enabled checkbox (true)
Assertion Consumer URIs /samlacs/acs
ACS Requires SSL checkbox (false)
SSL Client Identity Alias faisal_key
SSL Client Identity Pass Phrase password
POST Recipient Check Enabled checkbox (true)
POST one Use Check Enabled checkbox (true)
Used Assertion Cache Properties APID=ap_00001

Deploy and activate the applications

Domain Application

SamlSource samlsourceApp.war
SamlDestination samldest01App.war

Create user and group

The applications are designed to restrict access to its protected resource and only user with principal “SAML_SSO_GRP” has authorized access.So create a group “SAML_SSO_GRP” and user “samluser” and assign it to group “SAML_SSO_GRP” in both the domains.
Access the application with the following url

http://localhost:8080/samlsourceApp/index.jsp

Provide the username and password in the BASIC Authentication window.
Access the destination application by clicking on the destination application link.

Configuring two way SSL between Client and Weblogic server with Apache proxying the request.

Configure Apache for SSL

Create the certificates using openssl (present in apache_home\bin) using the below steps:

openssl genrsa -des3 -out server.key 1024

openssl req -config ..\conf\openssl.cnf -new -key server.key -out localhost

openssl x509 -req -days 730 -in localhost -signkey server.key -out server.crt

Add the following in the httpd.conf file

<IfModule ssl_module>
SSLRandomSeed startup builtin
SSLRandomSeed connect builtin
</IfModule>

Listen 443
<VirtualHost *:443>
SSLEngine on
SSLCertificateFile “C:\Program Files\Apache Group\Apache2\conf\server.crt”
SSLCertificateKeyFile “C:\Program Files\Apache Group\Apache2\conf\server.key”
SSLCACertificateFile “C:\Documents and Settings\Administrator\Desktop\cert\IntermediateCA.cer”
#SSLLog “C:\Program Files\Apache Group\Apache2\conf\ssl.log”
#SSLLogLevel debug
</VirtualHost>

Configure SSL between Apache and Weblogic Server

Add the following in the Location Directive

SecureProxy ON
TrustedCAFile C:\bea101\wlserver_10.0\server\lib\CertGenCA.pem
RequireSSLHostMatch false

Configure Apache to Request for Client Certificate

Add the following in the Location Directive

SSLVerifyClient optional_no_ca
SSLOptions +ExportCertData

Configure Weblogic Server for 2-way SSL

mydomain> Servers> myserver>Keystores & SSL > Advanced Options
Hostname Verification: None
Two Way Client Cert Behavior: Client Certs Requested but not enforced

Apache_SSL> Domain Wide Security Settings> Realms> myrealm> Authentication Providers> DefaultIdentityAsserter

Trusted Client Principals: provide CN of the Client Certificate
Types: X509

Details:

Use Default User Name Mapper: Checked
Default User Name Mapper Attribute Type: CN
Base64Decoding Required: Checked

Go the security realm and create a user wih the username as CN of the certificate

Add the following in the config.xml
<Server ClientCertProxyEnabled=”true”

Configure the Web Application

The Web Application should require client cert authentication.

Add the following in the web.xml

<context-param>
<param-name>weblogic.httpd.clientCertProxy</param-name>
<param-value>true</param-value>
</context-param>

Add the following in the weblogic.xml

<principal-name> CN of the certificate</principal-name>

References

1. http://www.apache-ssl.org/docs.html#SSLVerifyDepth
2. http://edocs.bea.com/wls/docs81/config_xml/Cluster.html#ClientCertProxyEnabled
3. http://httpd.apache.org/docs/2.0/mod/mod_ssl.html#ssloptions

Creating Users in Weblogic Server Embedded LDAP Programatically.

I have received many requests from Clients for code snippet to create users programmatically.Below is a sample code by which we can create users in the Embedded LDAP of Weblogic Server.Put simple, this program creates an MBean Server connection, traverses to the relevant Mbean and invokes the right method to create the user.

Details can be found at this link.
http://download.oracle.com/docs/cd/E13222_01/wls/docs90/jmx/accessWLS.html
Use the following code is a JSP and do the necessary import and acess the jsp page.

User testuser will be created in the embedded ldap with the password as password.

Hashtable env = new Hashtable();
env.put(Context.INITIAL_CONTEXT_FACTORY,”weblogic.jndi.WLInitialContextFactory”); env.put(Context.SECURITY_PRINCIPAL, “weblogic”);
env.put(Context.SECURITY_CREDENTIALS, “weblogic”);
env.put(Context.PROVIDER_URL, “t3://10.10.71.52:7001”);
InitialContext ctx = new InitialContext(env);
MBeanServer wls = (MBeanServer) ctx.lookup(“java:comp/env/jmx/runtime”);
ObjectName userEditor = null;
ObjectName MBTservice = new ObjectName( “com.bea:Name=MBeanTypeService,” + “Type=weblogic.management.mbeanservers.MBeanTypeService”);
ObjectName rs = new ObjectName(“com.bea:Name=RuntimeService,”+”Type=weblogic.management.mbeanservers.runtime.RuntimeServiceMBean”);
ObjectName domainMBean = (ObjectName) wls.getAttribute(rs,”DomainConfiguration”); ObjectName securityConfig = (ObjectName) wls.getAttribute(domainMBean,”SecurityConfiguration”);
ObjectName defaultRealm = (ObjectName) wls.getAttribute(securityConfig,”DefaultRealm”);
ObjectName[] atnProviders = (ObjectName[]) wls.getAttribute(defaultRealm,”AuthenticationProviders”);

for (ObjectName providerName : atnProviders) {
if (userEditor == null) {
ModelMBeanInfo info = (ModelMBeanInfo) wls.getMBeanInfo(providerName);
String className = (String) info.getMBeanDescriptor().getFieldValue(“interfaceClassName”);
if (className != null) {
String[] mba = (String[]) wls.invoke( MBTservice, “getSubtypes”, new Object[] { “weblogic.management.security.authentication.UserEditorMBean” }, new String[] { “java.lang.String” });

for (String mb : mba)
if (className.equals(mb)) userEditor = providerName;
}
}
}

if (userEditor == null) throw new RuntimeException(“Could not retrieve user editor”);

try{

out.println(“Creating User : testuser”);
wls.invoke(userEditor,”createUser”,new Object[] {“testuser”,”password”,”test user”},new String[] {“java.lang.String”, “java.lang.String”,”java.lang.String”});
out.println(“Created User : testuser”);
}

catch(Exception e){
e.printStackTrace();
}
ctx.close();

Servlet Authentication Filter for Weblogic Server

A growing need exists to trap request coming to Weblogic Server before it reaches the Container. Weblogic Server’s presence in Single Signon environment is increasing hence it becomes imperative that Clients should have the knowledge on how to develop a Servlet Authentication Filter and plug it in with Weblogic Server. A SAF (Servlet Authentication Filter) can be used in many scenarios. One of the most common uses I have seen is in redirecting to SAML Provider Site for authentication.

The steps the create a SAF is pretty much the same as other Custom Providers are created in WLS

Following link has the details on how to create a Custom Provider and how to integrate it with WLS.
http://download.oracle.com/docs/cd/E12840_01/wls/docs103/dvspisec/servlet.html

Following is a working sample that I developed for one of my Client.

First we need to create an MDF (Mbean definition file)

SimpleSampleServletAuthenticationFilter.xml

<?xml version=”1.0″ ?>
<!DOCTYPE MBeanType SYSTEM “commo.dtd”>

<MBeanType
Name = “SimpleServletAuthenticationFilter”
DisplayName = “SimpleServletAuthenticationFilter”
Package = “examples.security.providers.saf.simple”
Extends = “weblogic.management.security.authentication.Authenticator”
Implements =”weblogic.management.security.authentication.ServletAuthenticationFilter”
PersistPolicy = “OnUpdate”
>

<MBeanAttribute
Name = “ProviderClassName”
Type = “java.lang.String”
Writeable = “false”
Preprocessor = “weblogic.management.configuration.LegalHelper.checkClassName(value)”
Default = “&quot;examples.security.providers.saf.simple.SimpleSampleServletAuthenticationFilter&quot;”
/>

<MBeanAttribute
Name = “Description”
Type = “java.lang.String”
Writeable = “false”
Default = “&quot;WebLogic Simple Sample Servlet Authentication Filter&quot;”
/>

<MBeanAttribute
Name = “Version”
Type = “java.lang.String”
Writeable = “false”
Default = “&quot;1.0&quot;”
/>

</MBeanType>

Create a Filter Class

TokenFilter.java

/**
*
* @author faisalk
*/

package examples.security.providers.saf.simple;

import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
import java.util.*;

public final class TokenFilter implements Filter
{

private FilterConfig filterConfig = null;

public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain)
throws IOException, ServletException
{
System.out.println(“In do filter”);
HttpServletRequest req = (HttpServletRequest)request;
HttpServletResponse res = (HttpServletResponse)response;

Enumeration names = ((HttpServletRequest)request).getHeaderNames();

while(names.hasMoreElements()){
String name = (String) names.nextElement();
System.out.println(“Header Name “+name+” Content “+((HttpServletRequest)request).getHeader(name));
}

chain.doFilter(request,response);
}

public void destroy() { }

public void init(FilterConfig filterConfig) {
this.filterConfig = filterConfig;
}
}

The above filter just prints out the headers.

Finally create Provider Class

SimpleSampleServletAuthenticationFilter.java

/**
*
* @author faisalk
*/

package examples.security.providers.saf.simple;

import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.login.AppConfigurationEntry;
import weblogic.management.security.ProviderMBean;
import weblogic.security.service.ContextHandler;
import weblogic.security.spi.AuthenticationProviderV2;
import weblogic.security.spi.ServletAuthenticationFilter;
import weblogic.security.spi.IdentityAsserterV2;
import weblogic.security.spi.IdentityAssertionException;
import weblogic.security.spi.PrincipalValidator;
import weblogic.security.spi.SecurityServices;
import javax.servlet.Filter;

public final class SimpleSampleServletAuthenticationFilter implements AuthenticationProviderV2, ServletAuthenticationFilter
{

private String description; // a description of this provider

public void initialize(ProviderMBean mbean, SecurityServices services)
{
System.out.println(“SimpleSampleServletAuthenticationFilter.initialize”);

}

public String getDescription()
{
return description;
}

public void shutdown()
{
System.out.println(“SimpleSampleServletAuthenticationFilter.shutdown”);
}

public IdentityAsserterV2 getIdentityAsserter()
{
return null;
}

public Filter[] getServletAuthenticationFilters()
{
System.out.println(“SimpleSampleServletAuthenticationFilter.getServletAuthenticationFilters”);

Filter[] filters = new Filter[1];
TokenFilter token = new TokenFilter();
filters[0]= token;
return filters;
}

public AppConfigurationEntry getLoginModuleConfiguration()
{
return null;
}

public AppConfigurationEntry getAssertionModuleConfiguration()
{
return null;
}

public PrincipalValidator getPrincipalValidator()
{
return null;
}
}

The details of the interfaces implemented are there in the official site.
You can get more details there. I am not covering the details of the API for now

Copy the three files in a folder.
Keep the following build script to the same folder

build.xml

<!– @author Faisal Khan–>

<project name=”Expenselink Build” default=”all” basedir=”.”>

<property name=”fileDir” value=”test” />

<target name=”all” depends=”build”/>

<target name=”build” depends=”clean,build.mdf,build.mjf”/>

<target name=”clean”>
<delete dir=”${fileDir}” failonerror=”false”/>
<delete file=”SimpleSampleServletAuthenticationFilter.jar” failonerror=”false”/>
<echo message=”Clean finish” />
</target>

<!– helper to build an MDF (mbean definition file) –>
<target name=”build.mdf”>
<java dir=”${basedir}” fork=”false” classname=”weblogic.management.commo.WebLogicMBeanMaker”>
<arg line=”-files ${fileDir}” />
<arg value=”-createStubs” />
<arg line=”-MDF SimpleSampleServletAuthenticationFilter.xml” />
</java>
<echo message=”Created Supporting Classes” />
</target>

<target name=”build.mjf”>

<copy todir=”${fileDir}” flatten=”true”>
<fileset dir=”.”>
<include name=”*.java” />
</fileset>
</copy>

<java dir=”${basedir}” fork=”false” classname=”weblogic.management.commo.WebLogicMBeanMaker”>
<arg line=”-MJF SimpleSampleServletAuthenticationFilter.jar” />
<arg line=”-files ${fileDir}” />
</java>
<echo message=”Created Mbean Jar” />
</target>

</project>

Copy commo.dtd present in server lib to this directory.
Run setWLSEnv.cmd and cd to this directory.
Type ant in the command prompt
A Servlet Authenticator Filter jar file would be created.

Place this jar file in WL_HOME\server\lib\mbeantypes
Restart the Server.
Go to Security Realm Providers, create a new Authentication Provider
Home > Summary of Security Realms > myrealm > Providers > Authentication > SAF
Restart the server.

Whenever any protected resource is accessed, the SAF is invoked.