views:

755

answers:

3

Hi,

I'm developing a webapp which allows for two types for users - User and Admin.

There's are two parts of the site - the User side, and the Admin side. I'm using Spring Security to secure both sites and its working pretty well except I've come across a bit of a problem.

Basically, if the user is not logged in and tries to access a page on either part of the site, they should be directed to a different login page. For example:

  • user is not logged in and tries to access a page which only Users can see -> user is intercepted and is directed to LoginPageOne.jsp

The other case would then be:

  • user is not logged in and tries to access a page which only Admins can see -> user is intercepted and is directed to LoginPageTwo.jsp

I've tried to do this a number of ways without any success. First of all I tried to create two seperate sets of intercept-urls in my applicationContext-security.xml which would use different entry-point-refs which would in turn point to different login URLs. This failed - the webapp wouldnt even start.

Now I'm trying to extend the AuthenticationProcessingFilterEntryPoint but I don't know how to forward the user based on the resource they're trying to access. I was hoping I could find out what Roles the user needs in order to access the resource and based off that, forward them to the correct page but I'm not sure this is possible.

I've done a fair bit of searching across the interwebs and haven't managed to find a solution for my problem so any help with this would be greatly appreciated :-)

Thanks, Ger.

A: 

One approach would be to extend AuthenticationProcessingFilter to override

protected String determineFailureUrl(HttpServletRequest request, 
                                     AuthenticationException failed);

Then, based on the request URL and the authentication exception, decide the entry point URL.

rodrigoap
I could be wrong but doesn't that method only get invoked AFTER the user has attempted to login (rather than when Spring Security interrupts the user).
Gearóid
A: 

Sample of config:

<http auto-config="false" entry-point-ref="authenticationProcessingFilterEntryPoint" >
            <intercept-url pattern="/user" access="ROLE_USER"/>
            <intercept-url pattern="/admin" access="ROLE_ADMIN"/>        
            <form-login login-page="/adminlogin" authentication-failure-url= "/adminlogin?error=true" default-target-url="/admin" />
</http>

<beans:bean id="authenticationProcessingFilterEntryPoint"
            class="your.package.CustomAuthenticationProcessingFilterEntryPoint">
    <beans:property name="loginFormUrl" value="/adminlogin"/>
    <beans:property name="userLoginFormUrl" value="/userlogin"/>
    <beans:property name="forceHttps" value="false"/>

and the class:

public class CustomAuthenticationProcessingFilterEntryPoint extends AuthenticationProcessingFilterEntryPoint {
@Override
    protected String determineUrlToUseForThisRequest(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) {
//check request.getRequestURI() and return where you need to redirect user.
}
sab
It seems that the two loginFormUrl's causes the application to fail on startup - any idea how it would be possible to pass in these url's through the spring config? It would be much nicer to do this rather than hardcoding into the custom filter entry point
Gearóid
A: 

Since version 3 Spring Security introduces org.springframework.security.web.authentication.DelegatingAuthenticationEntryPoint.

It serves as a Proxy which allows you to inject many entry point into it and decide at the runtime which point should be chosen for particular request.

It is quite simple for use but if you got any problems with it - just let me know in comment.

Henryk Konsek

related questions