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.

32 comments

  1. 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

  2. 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.

  3. Hi Faisal,

    You have really give straight forward steps to configure "Servlet Authentication Filter for Weblogic Server".

    Thanks,
    Mahesh

  4. Hi Faisal,

    You have really give straight forward steps to configure "Servlet Authentication Filter for Weblogic Server".

    Thanks,
    Mahesh

  5. 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?!

  6. which jar file contain these classes? weblogic.security.spi.AuthenticationProviderV2/weblogic.security.service.ContextHandler etc.

  7. 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?

    1. 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

  8. 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

  9. 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.

    1. 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!

  10. 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

    1. 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

  11. 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?

    1. 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…

  12. Hello,
    I’m a bit new to weblogic security and need your help to implement SSO + NTLM for an intranet appliaction. The objective is to have an application deployed on wl that we can access from the company Windows clients without having to logon again. For that, I have started with a simple NTLM servlet authentication filter based on http://www.coderanch.com/t/522578/JSP/java/After-adding-servlet-filter-check and “servlet authentication filter” as explained in weblogic-wonders. I’m able to deploy the authentication filter to weblogic and to obtain the username from the browser. Besides this, I have configured an active directory authenticator and try to check if the obtained user (from the filter) exists in the active directory (via the active directory authenticator). My questions are:
    1- How to implement the user check between the filter and the active directory?
    2- Do I need an identity assertion provider or not?

    Any additional suggestions are welcome.
    Thank you for your help.

  13. Hi,

    I have created Custom Role Mapping Provider.
    We are facing one issue, after deploying MBean.jar file. Below is the process on how we got the error:

    1)Placed MBean.jar file into C:\Oracle\Middleware\wlserver_10.3\server\lib\mbeantypes
    2)Deployed MBean.jar file into Weblogic Administration Console. Successfully deployed without errors.
    3)Created Custom Role Mapping Provider(i.e,SRMP) with Type “SampleRoleMapper”(SampleRoleMapper Type developed in MBean.jar file).
    4)After creating Custom Role Mapping Provider, Weblogic forced to restart.(In order to get provider specific attributes).

    So, while restarting the web logic server, prompting an error as “com.bea.common.engine.SecurityServiceRuntimeException:[Security:097533]Security provider service class name for ”SRMP” is not specified.

    Can you please help me out to solve this problem?

    Thank you in advance.

  14. i’ve tried to implement the JSP as described in the above.. But it turns out that the Filter is not invoked by requests pointing to an deployed web application. I deployed it with an advanced security model and the JAAS control flag is “required” ..

    Any help for this is highly appreciated

  15. Hi,

    I’m doing a project for an university course and I was following your tutorial (which is really easy to follow) and I made my SAF but it dose not appear as a provider. I’m using WLS 12.1, can this be the problem? If yes can you tell me what should I do differently?

    Thank you!

  16. Hi,

    I have a question on how frequently a ServletAuthenticationFilter should be invoked:

    Would you expect it to be invoked on every request for a protected resource (even when the user has an authenticated session)

    or

    Would you expect it to be invoked only on the authentication request (equivalent to login) and logout.

    I had thought / expected that a ServletAuthenticationFilter would be invoked on every request and would give us the opportunity to inspect the incoming request but it appears to be only invoked on the first request by a user. Once they have a session + JSESSIONID allocated the ServletAuthenticationFilter is not invoked again.

    You have a line in the above article which says ‘Whenever any protected resource is accessed, the SAF is invoked.’ – that is what I would expect to happen.

    Thank you very much.

    1. Hi Paul,

      I should have added that whenever a protected resource is accessed for the first time.
      You will have to think of an alternate way.

      Regards,
      Faisal

  17. Thank you for the wonderful post. I am like the one before me too, where I am using weblogic 12c and am not able to find the SAF provider in the dropdown list. I see a whole bunch of Asserter and Authenticator in the Provider “Type” dropdown list, but nothing for Servlet Authentication Filter. Do you know why?

Leave a Reply