Spring Security using Websphere & JSF - Unauthenticated problem
Hi,
I'm using Websphere 7 and Spring Security 3 and keeps getting UNAUTHENTICATED after I login.
My web.xml:
<security-constraint>
<web-resource-collection>
<web-resource-name>All_Admin_User</web-resource-name>
<description />
<url-pattern>*</url-pattern>
<http-method>GET</http-method>
<http-method>POST</http-method>
<http-method>PUT</http-method>
<http-method>DELETE</http-method>
</web-resource-collection>
<auth-constraint>
<role-name>Authenticated User</role-name>
</auth-constraint>
</security-constraint>
My applicationContext-security.xml:
<sec:http auto-config="true" realm="Demo EOL Login" use-expressions="true" access-denied-page="/accessDenied.jsp" >
<sec:intercept-url pattern="/internal/**" access="hasRole('ROLE_VIEW_EARS_ONLINE')" />
<sec:intercept-url pattern="/external/**" access="hasRole('ROLE_VIEW_EARS_ONLINE')" />
<sec:intercept-url pattern="/**" access="permitAll" />
<sec:form-login/>
<sec:custom-filter position="PRE_AUTH_FILTER" ref="webspherePreAuthFilter" />
</sec:http>
The log from websphere:
MyWebSpherePreAuthenticatedProcessingFilter - principal name is UNAUTHENTICATED
Authentication a is null
I'm using form login for my login_j2ee.jsp I also using the j_spring_security_check action:
<form name="logonForm" action="j_spring_security_check" method="post">
But some how Websphere can't authenticate my login.
Anyone who has had the same problem and managed to solve it?
Kind regards
Jerry Johansson
applicationContext-security.xml (To use with Tomcat)
Use this file for Tomcat.
Cheers
Jerry Johansson, Perth
File applicationContext-security.xml:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:sec="http://www.springframework.org/schema/security" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schem...-beans-3.0.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-3.0.3.xsd">
<bean id="filterChainProxy" class="org.springframework.security.web.FilterChai nProxy">
<sec:filter-chain-map path-type="ant">
<sec:filter-chain pattern="/**"
filters="sif,j2eePreAuthFilter,logoutFilter,etf,fs i" />
</sec:filter-chain-map>
</bean>
<bean id="sif"
class="org.springframework.security.web.context.Se curityContextPersistenceFilter" />
<sec:authentication-manager alias="authenticationManager">
<sec:authentication-provider ref='preAuthenticatedAuthenticationProvider' />
</sec:authentication-manager>
<bean id="preAuthenticatedAuthenticationProvider"
class="org.springframework.security.web.authentica tion.preauth.PreAuthenticatedAuthenticationProvide r">
<property name="preAuthenticatedUserDetailsService" ref="myPreAuthenticatedUserDetailsService" />
</bean>
<bean id="preAuthenticatedUserDetailsService"
class="org.springframework.security.web.authentica tion.preauth.PreAuthenticatedGrantedAuthoritiesUse rDetailsService" />
<bean id="myPreAuthenticatedUserDetailsService"
class="com.apps.admin.security.MyPreAuthenticatedG rantedAuthoritiesUserDetailsService">
</bean>
<bean id="j2eePreAuthFilter"
class="org.springframework.security.web.authentica tion.preauth.j2ee.J2eePreAuthenticatedProcessingFi lter">
<property name="authenticationManager" ref="authenticationManager" />
<property name="authenticationDetailsSource">
<bean
class="org.springframework.security.web.authentica tion.preauth.j2ee.J2eeBasedPreAuthenticatedWebAuth enticationDetailsSource">
<property name="mappableRolesRetriever">
<bean
class="org.springframework.security.web.authentica tion.preauth.j2ee.WebXmlMappableAttributesRetrieve r" />
</property>
<property name="userRoles2GrantedAuthoritiesMapper">
<bean
class="org.springframework.security.core.authority .mapping.SimpleAttributes2GrantedAuthoritiesMapper ">
<property name="convertAttributeToUpperCase" value="true" />
</bean>
</property>
</bean>
</property>
</bean>
<bean id="preAuthenticatedProcessingFilterEntryPoint"
class="org.springframework.security.web.authentica tion.Http403ForbiddenEntryPoint" />
<bean id="logoutFilter"
class="org.springframework.security.web.authentica tion.logout.LogoutFilter">
<constructor-arg value="/" />
<constructor-arg>
<list>
<bean
class="org.springframework.security.web.authentica tion.logout.SecurityContextLogoutHandler" />
</list>
</constructor-arg>
</bean>
<bean id="servletContext"
class="org.springframework.web.context.support.Ser vletContextFactoryBean" />
<bean id="etf"
class="org.springframework.security.web.access.Exc eptionTranslationFilter">
<property name="authenticationEntryPoint" ref="preAuthenticatedProcessingFilterEntryPoint" />
</bean>
<bean id="httpRequestAccessDecisionManager"
class="org.springframework.security.access.vote.Af firmativeBased">
<property name="allowIfAllAbstainDecisions" value="false" />
<property name="decisionVoters">
<list>
<ref bean="roleVoter" />
</list>
</property>
</bean>
<bean id="fsi"
class="org.springframework.security.web.access.int ercept.FilterSecurityInterceptor">
<property name="authenticationManager" ref="authenticationManager" />
<property name="accessDecisionManager" ref="httpRequestAccessDecisionManager" />
<property name="securityMetadataSource">
<sec:filter-invocation-definition-source>
<sec:intercept-url pattern="/internal/**" access="ROLE_VIEW_ONLINE" />
<sec:intercept-url pattern="/external/**" access="ROLE_VIEW_ONLINE" />
</sec:filter-invocation-definition-source>
</property>
</bean>
<bean id="roleVoter" class="org.springframework.security.access.vote.Ro leVoter" />
<bean id="securityContextHolderAwareRequestFilter"
class="org.springframework.security.web.servletapi .SecurityContextHolderAwareRequestFilter" />
<!-- <sec:global-method-security
pre-post-annotations="enabled" />
-->
</beans>
File: WasPreAuthenticatedUserDetailsService
Below is my WasPreAuthenticatedUserDetailsService, to actually get the grantedAuthorities from the Autentication token, from Websphere and in my case LDAP, and do the validation.
(I have changed the content a bit for package names and variables name for protection)
Cheers
Jerry Johansson, Perth
File WasPreAuthenticatedUserDetailsService:
package com.apps.admin.security;
import com.apps.admin.util.Constants;
import java.util.ArrayList;
import java.util.List;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationEx ception;
import org.springframework.security.core.GrantedAuthority ;
import org.springframework.security.core.authority.Grante dAuthoritiesContainer;
import org.springframework.security.core.authority.Grante dAuthorityImpl;
import org.springframework.security.core.userdetails.Auth enticationUserDetailsService;
import org.springframework.security.core.userdetails.User ;
import org.springframework.security.core.userdetails.User Details;
import org.springframework.security.core.userdetails.User nameNotFoundException;
import org.springframework.util.Assert;
import com.apps.framework.objectclass.Person;
import com.apps.admin.ldap.AppsLDAP;
import com.apps.admin.service.UserService;
import com.apps.admin.util.AppsProperty;
import org.springframework.beans.factory.annotation.Autow ired;
import org.springframework.beans.factory.annotation.Quali fier;
public class WasPreAuthenticatedUserDetailsService implements AuthenticationUserDetailsService {
@Autowired
@Qualifier("userService")
private UserService userService;
List<GrantedAuthority> authAuthorities;
public List<GrantedAuthority> getAuthAuthorities() {
return authAuthorities;
}
public void setAuthAuthorities(List<GrantedAuthority> authAuthorities) {
this.authAuthorities = authAuthorities;
}
/**
* Get a UserDetails object based on the user name contained in the given
* token, and the GrantedAuthorities as returned by the
* GrantedAuthoritiesContainer implementation as returned by
* the token.getDetails() method.
*/
@Override
public UserDetails loadUserDetails(Authentication token)
throws UsernameNotFoundException {
Assert.notNull(token.getDetails());
Assert.isInstanceOf(GrantedAuthoritiesContainer.cl ass, token.getDetails());
List<GrantedAuthority> roles = new ArrayList<GrantedAuthority>();
validateAndSetPermissions(token, roles);
UserDetails ud = createuserDetails(token, roles);
return ud;
}
private void validateAndSetPermissions(Authentication token, List<GrantedAuthority> roles){
boolean isAppsOnlineUser = false;
boolean isAppsMineralBusinessAdmin = false;
boolean isAppsPetroleumBusinessAdmin = false;
List<GrantedAuthority> authorities = ((GrantedAuthoritiesContainer) token.getDetails()).getGrantedAuthorities();
if(authorities != null){
for(GrantedAuthority myAuth : authorities){
if(myAuth.equals("CN=Apps ONLINE USER,OU=Apps,OU=SYSTEMS,O=CORP")){
isAppsOnlineUser = true;
}
else if(myAuth.equals("CN=Apps MINERALS BUSINESS ADMIN,OU=Apps,OU=SYSTEMS,O=CORP"))
{
isAppsMineralBusinessAdmin = true;
}
else if(myAuth.equals("CN=Apps PETROLEUM BUSINESS ADMIN,OU=Apps,OU=SYSTEMS,O=CORP"))
{
isAppsPetroleumBusinessAdmin = true;
}
}
if(isAppsOnlineUser){
Person person = AppsLDAP.getPersonAppsOnly(token.getName());
roles.add(new GrantedAuthorityImpl(Constants.SECURITY_ROLES.VIEW _Apps_ONLINE));
if(isAppsMineralBusinessAdmin)
{
roles.add(new GrantedAuthorityImpl(Constants.SECURITY_ROLES.VIEW _CORP_ADMIN));
}
if(isAppsPetroleumBusinessAdmin)
{
roles.add(new GrantedAuthorityImpl(Constants.SECURITY_ROLES.VIEW _CORP_ADMIN));
}
// Validating if user is Internal or External
boolean isExternal = AppsLDAP.CATEGORY_EXTERNAL.equals(person.getCatego ry().getDescription()); //External
if(isExternal){
GrantedAuthority externalAuth = new GrantedAuthorityImpl(Constants.SECURITY_ROLES.VIEW _Apps_ONLINE_EXTERNAL);
roles.add(externalAuth);
System.out.println("Adding 'View Apps Online EXTERNAL' rights");
}else{
GrantedAuthority internalAuth = new GrantedAuthorityImpl(Constants.SECURITY_ROLES.VIEW _Apps_ONLINE_INTERNAL);
roles.add(internalAuth);
System.out.println("Adding 'View Apps Online INTERNAL' rights");
}
List<String> userRoles = new ArrayList();
try{
userRoles = userService.getRoles(token.getName());
}
catch(Exception e){
System.out.println("userService.getRoles failed with userID: " + token.getName());
}
int i = 0;
for(String role: userRoles) {
if(role != null && role.length() > 0) {
i++;
roles.add(new GrantedAuthorityImpl(role));
System.out.println("Adding role from DB: " + role);
}
}
if(isExternal && i==0){
System.out.println("External User " + token.getName() + " has no roles assigned. NOT an external admin user, will be rejected access.");
}
}
}
}
/**
* Creates the final <tt>UserDetails</tt> object. Can be overridden to customize the contents.
*
* @param token the authentication request token
* @param authorities the pre-authenticated authorities.
*/
protected UserDetails createuserDetails(Authentication token, List<GrantedAuthority> authorities) {
return new User(token.getName(), "N/A", true, true, true, true, authorities);
}
}