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 = “"examples.security.providers.saf.simple.SimpleSampleServletAuthenticationFilter"”
/>
<MBeanAttribute
Name = “Description”
Type = “java.lang.String”
Writeable = “false”
Default = “"WebLogic Simple Sample Servlet Authentication Filter"”
/>
<MBeanAttribute
Name = “Version”
Type = “java.lang.String”
Writeable = “false”
Default = “"1.0"”
/>
</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.
20 Comments
The xml files can not be pasted for some reason. If anyone requires them they can mail me at khan.faysal06@gmail.com. I'll b glad to share.
gud work..
Any estimate on the time front and How does this differ in various situations like
"Trap the request coming to Weblogic Server before it reaches the Container"….as you said how does the growing need differ in and what all situations???? Looking forward to your response
Hi Ajay,
Thanks for your interest in this blog. If I uderstand the first part correctly, you mean the overhead on the server? Yes there is certain overhead but I have not done any benchmarking and performance testing with SAF and without SAF.
Second question is interesting.. SAF can be used in many scenarios where token based authentication is done. I have also seen customer's emplying SAF to consume some unsupported tokens like DIGEST.
Thanks a lot for the reply.
Waiting for more posts…
Hi Faisal,
You have really give straight forward steps to configure "Servlet Authentication Filter for Weblogic Server".
Thanks,
Mahesh
Hi Faisal,
You have really give straight forward steps to configure "Servlet Authentication Filter for Weblogic Server".
Thanks,
Mahesh
Faisal, thanks for this concise description.
I had an issue with my customer security provider not appearing in the BEA console, and yours does appear! So I shall use this as a template.
By the way, anyone knows why commo.dtd does not define the Preprocessor element that is used everywhere?!
which jar file contain these classes? weblogic.security.spi.AuthenticationProviderV2/weblogic.security.service.ContextHandler etc.
i got these classes in the following jar:
com.bea.core.weblogic.security_2.0.1.0.jar etc.
Hi Faisal,
Thank you for a good filter sample.
I built a test filter from the files above and installed it in Weblogic 10. However, for some reason the filter seems to be invoked only if the user’s password is incorrect. If the user authenticates with a good password the filter (doFilter) is just not invoked. The filter is places on the top of the authentication provider list and has the REQUIRED flag. Do you have any idea what is wrong?
The filter should be invoked when you access any secured resource on WLS.
The filter is trigered before the process of Authentication, so ideally wat u r describing should not happen.
Can u provide more details on how u r trying to authenticate?
Can u add some debug and paste it here.
Also enable Security Debugs on WLS and paste it here.
Thanks for posting
Faisal
Thanks for the posting the good article , however SAF
does not work for me, I am using WLS 10.3.5 ,
I do see getServeltAuthenticationFilters() being invoked, but I am never able to intercept a request in Filter class,am I missing something?
Thank you,
hp
Hi Hardik,
I have sent you SAF code.
It should work.
Thanks,
Faisal
Faisal,
In my setup, I need an Identity Assertion Provider, as well as a Servlet Authentication Filter. In this situation, should my provider implementation be a single concrete class that implements all 3 interfaces (AuthenticationProviderV2, IdentityAsserterV2, and ServletAuthenticationFilter)? Or 2 separate implementations?
What’s the implication of doing it one way or the other?
If I use a single concrete class, would I still have to create 2 MBean types?
Thanks in advance.
Hi Ansary,
I did it long time back.
We can have the SAF and Identity Asserter in the same file, but if I remember correctly only one gets called.
I will look up my test case for you and if i find it, ill mail it across.
Cheers!
Hi Faisal,
Is there a way by which I can completely disable the authentication at WLS level.
I am working on an OUAF based product ( Oracle Utility CC&B V2.x to be specific). The application runs on weblogic application server and has no authentication scheme of it’s own ( no passwords stored anywhere). Theauthentication is taken care of at the WLS level only.
I am curious to know if there is any possible way by which, the application can be made authentication free i.e logging in with just the user id and no passwords..??
All my best regards,
Karishma
Hi Karishma,
Do you want no authentication or authentication that requires only userid?
If you don’t want authentication then remove security constraints from the deployment descriptors.
If you want users to be authenticated only by their userid, then you can develop a custom authenticator.
Thanks,
Faisal
Hello,
I followed the steps in WL 10.3.5. However while creating a new authentication provider in the last step, I dont see SAF as a type option. I can see SAML authenticator and the rest in the drop down list. I am new to these. What am I missing?
in 10.3.5 the package structure might have changed.. there could be few jars missing.. can you try on 10.3 and see if it works?
if your mbean jar is created properly it should show up…
Post a Comment