Customize target URL according to the user ROLE with Spring Security 2

It’s there some idea about this issue, but I think there’s no simple solution exposed.

You can achieve this behaviour by modifying applicationContext.xml and by extending Spring’s AuthenticationProcessingFilter.

applicationContext.xml

<!-- Spring Security Authentication -->
<http auto-config="false" entry-point-ref="authenticationProcessingFilterEntryPoint">
<!-- LITERAL user can only access to literal pages -->
<intercept -url pattern="/*iteral.htm" access="ROLE_LITERAL,ROLE_ADMIN" />
<!-- ADMIN user can access everywhere -->
<intercept -url pattern="/**.htm" access="ROLE_ADMIN" />
</http>

<!-- User list -->
<authentication -provider>
<password -encoder hash="md5"/>
<user -service>
<user name="admin" password="21232f297a57a5a743894a0e4a801fc3" authorities="ROLE_ADMIN" />
<user name="literals" password="b284ec8f1c7a6208901d2a5d27d17a32" authorities="ROLE_LITERAL" />
</user>
</authentication>

<!-- Entry point properties -->
<authentication -manager alias="authenticationManagerAlias"/>
<bean id="authenticationProcessingFilterEntryPoint" class="org.springframework.security.ui.webapp.AuthenticationProcessingFilterEntryPoint">
<property name="loginFormUrl" value="/login.htm"/>
<property name="forceHttps" value="false" />
</bean>
< -- Custom Authentication Processing Filter -->
<bean id="customAuthenticationProcessingFilter" class="CustomAuthenticationProcessingFilter">
<property name="filterProcessesUrl" value="/j_spring_security_check" />
<property name="defaultTargetUrl" value="/index.sdf"/>
<property name="authenticationManager" ref="authenticationManagerAlias"/>
<custom -filter position="AUTHENTICATION_PROCESSING_FILTER"/>
</bean>

Custom Authentication Processing Filter

public class CustomAuthenticationProcessingFilter extends AuthenticationProcessingFilter {

  public static final String ROLE_ADMIN = "ROLE_ADMIN";

  private static final String ROLE_ADMIN_TARGET_URL = "/index.htm";
  private static final String NON_ROLE_ADMIN_TARGET_URL = "/literal.htm";

  @Override
  protected String determineTargetUrl(HttpServletRequest request) {

    boolean isAdmin = hasRole(ROLE_ADMIN); 

    String targetUrl;
    if (isAdmin) {
      targetUrl = ROLE_ADMIN_TARGET_URL;
    } else {
      targetUrl = NON_ROLE_ADMIN_TARGET_URL;
    }

    return targetUrl;
  }

  /**
    * Returns true is user authenticated has role
    */
  public static boolean hasRole(String role) {

    boolean userHasRole = false;
    GrantedAuthority[] grantedAuthorities = SecurityContextHolder.getContext().getAuthentication().getAuthorities();

    for (GrantedAuthority grantedAuthority : grantedAuthorities) {
      if (role.equals(grantedAuthority.toString())) {
        userHasRole = true;
        break;
      }
    }

    return userHasRole;

  }

}

It seems simple, however, it becomes complex because of Spring Security documentation, which is results very poor for integration purposes.

Anuncios

Spring Security 2.0 and Spring 2.0.X

Spring Security allows applications to include authentication features in J2EE applications with a very few effort. However, configuration in previous versions, like Acegi Security, was a hard task to perform by a newcomer. Spring people talks about a difference of a hundred of configuration lines between Acegi 1.0 (120 lines for configuration) and Security 2.0 (just only 16 lines). So, it’s highly advisable to use Spring Security 2.0.

These links can help in developing a small sample:

In our case, form based authentication via user/password in a webapp, we’ve include two minor adjustments in web.xml (webapp container configuration) and applicationContext.xml (Spring configuration).

web.xml


    springSecurityFilterChain
    org.springframework.web.filter.DelegatingFilterProxy


  springSecurityFilterChain
  /*

* I’ve replaced – character for _ character in this XML file

applicationContext.xml




    


    


    
    
        
    

[...]

* I’ve replaced – character for _ character and : character for __ characters in this XML file to get a suitable visualization

Development of login.jsp page is detailed in several resources, such as here.

It could be wonderful, but there is one important point for us which is poorly documented. Spring Security 2.0 only works with Spring 2.0.8. And we are using BEA Weblogic 10. And BEA Weblogic 10 only certifies the use of Spring 2.0.2. 

So we have now a dangerous decision: shall we use Spring Security 2.0 and Spring 2.0.8 and loose BEA (I mean Oracle) support or shall we use Acegi Security 1.0 and Spring 2.0.2 and write tedious and hard to maintain configuration files?