4

Short version: In pure Java EE 6, is there something like Spring's Authentication Processing Filter, which customizes form-based authentication?

Long version: I'm working on a pure Java EE 6 web application (JSF2, CDI), which must be independent of the concrete Java EE 6 container used later.

JSF2 pages with restricted access are stored in a sub-folder /pages. In my web.xml, I defined the following to restrict access to those pages:

<login-config>
    <auth-method>FORM</auth-method>
    <realm-name>??????????</realm-name>
    <form-login-config>
        <form-login-page>/login.jsf</form-login-page>
        <form-error-page>/access_denied.jsf</form-error-page>
    </form-login-config>
</login-config>

<security-constraint>
    <display-name>pages_auth</display-name>
    <web-resource-collection>
        <web-resource-name>pages</web-resource-name>
        <url-pattern>/pages/*</url-pattern>
    </web-resource-collection>
    <auth-constraint>
        <role-name>AuthenticatedUser</role-name>
    </auth-constraint>
</security-constraint>

<security-role>
    <role-name>AuthenticatedUser</role-name>
</security-role>

As indicated by the "????" in the code above, I can't use one of the pre-defined realms like JDBC, because the autentication to use is very custom (nasty detail: credentials are checked against an ugly legacy system) and requires some Java coding.

I expected that I could create a new class implementing some interface overriding some authenticate method with the parameters "login" and "password" returning a boolean to denote a successful authentication.

However, after reading several hours on the topic, I'm totally lost :-( Do I need to implement a JAAS LoginModule and Realm? This looks very complicated to me. Or is there another standard Java EE 6 way to do it? Or do I need to go the way of implementing a ServletFilter instead?

3 Answers 3

2

Into the realm-name tag you need to put what's the name of realm that you create in container. It's not realm type, it's only the realm name chosen by you.

I have an app using JBoss AS, and bellow my configuration as example:

web.xml

<realm-name>weblog-jaas-realm</realm-name>

standalone.xml

<security-domain name="weblog-jaas-realm">
    <authentication>
        <login-module code="Database" flag="required">
            [...]
        </login-module>
    </authentication>
</security-domain>
Sign up to request clarification or add additional context in comments.

Comments

1

I ended up using Spring Security. It seems with Java EE 6 libraries, it is not easily possible to implement a custom authentication provider. Of course you can implement everything from scratch using servlet filters, but that's in my view too error prone. Spring Security seems to be a good solution even though it adds many libraries to my webapp, which I hoped I could get around without.

Comments

1

Rather than considering writing your own custom realm, and certainly not considering use of servlet filters, you would achieve this fairly easily using an appropriate JAAS LoginModule implementation. We have done this quite successfully across a number of different Java EE containers including Tomcat, WebLogic and WebSphere.

Whilst JAAS defines the APIs clearly, making your LoginModule implementation portable, you will find that how JAAS is configured in each container is different and you may have to mess about with setting up appropriate principal name and role principal implementation mappings to make it work.

2 Comments

Just to make sure I understood it correctly: The implementation of the LoginModule would stay portable, but just the way it is wired up is non-portable?
@Sebi The LoginModule is unfortunately not portable in the way Phil suggested it. At a minimum you need to provide proprietary Principals that represent the user/caller and the groups/roles. With the JASPIC API/SPI there is a portable way to wire the LoginModule or just do everything in a portable way inside the AuthenticationModule (called SAM). Wiring a SAM is portable when done from within an application. Wiring it inside the server itself is still proprietary, but if you went with Spring doing it from the app shouldn't be an issue for you.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.