In the previous part we looked how to secure the URL calls. Now let us look into how to secure the method invocation. Let us again have a properties file (methods.properties) that contains the method names and the roles that can invoke the methods. For example,
com.test.service.MyService.delete*=ROLE_USER,ROLE_MANAGER
com.test.service.MyService.createAccount=ROLE_ADMIN
You can also have this mapping defined in database or LDAP server. For simplicity we will have the mapping defined in a properties file.
Let us now define interface (IMyService) and implementation (MyService)
public interface IMyService {
public void deleteUserPreferences (String userName);
public void deleteUserLogs(String userName);
public void createAccount(String userName);
}
Now based on the above configurations ROLE_USER, ROLE_MANAGER would only be able to invoke the methods deleteUserPreferences and deleteUserLogs. ROLE_ADMIN would only be able to invoke method createAccount.
Now you can write MyService implementing the above interface.
Method security in enforced using a MethodSecurityInterceptor, which secures
MethodInvocations. The interceptor uses a MethodDefinitionSource instance to obtain the configuration attributes that apply to a particular method invocation. Since we would be reading the methods names and the corresponding roles from properties file, we would either –
1. Define our own implementation of MethodSecurityMetadataSource and implement all methods.
2. Or we can write a class extending MapBasedMethodSecurityMetadataSource. MapBasedMethodDefinitionSource is used to store configuration attributes keyed by method names (which can be wildcarded) and will be used internally when the attributes are defined in the application context using the <intercept-methods> or <protect-point> elements.
We will go ahead with point 2 as we just need to read the properties file, create Map<String, List<ConfigAttribute>> and call MapBasedMethodDefinitionSource’s constructor passing this map.
So, let us first define a bean PropertyHolder that would read the properties file and create Map<String, List<ConfigAttribute>>.
<bean id="propHolder" class="com.test.common.PropertyHolder">
<property name="methodProperties">
<util:properties location="classpath:methods.properties" />
</property>
</bean>
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import org.springframework.security.access.ConfigAttribute;
import org.springframework.security.access.SecurityConfig;
import org.springframework.util.StringUtils;
public class PropertyHolder {
private Properties methodProperties;
public void setMethodProperties(Properties methodProperties) {
this.methodProperties = methodProperties;
}
public Properties getMethodProperties() {
return methodProperties;
}
public Map<String, List<ConfigAttribute>> getMethodMap() {
Map<String, List<ConfigAttribute>> methodMap = new HashMap<String, List<ConfigAttribute>>();
for (Iterator iter = methodProperties.keySet().iterator(); iter
.hasNext();) {
String name = (String) iter.next();
String value = methodProperties.getProperty(name);
String[] tokens = StringUtils
.commaDelimitedListToStringArray(value);
List<ConfigAttribute> attributes = new ArrayList<ConfigAttribute>(
tokens.length);
for (String token : tokens) {
attributes.add(new SecurityConfig(token));
}
methodMap.put(name, attributes);
}
return methodMap;
}
}
Now let us configure a MethodSecurityIterceptor in our application context
<bean id="methodSecurityInterceptor" class="org.springframework.security.access.intercept.aopalliance.MethodSecurityInterceptor">
<property name="authenticationManager" ref="authenticationManager"/>
<property name="accessDecisionManager" ref="accessDecisionManager"/>
<property name="securityMetadataSource" ref="mySecurityMetadataSource"/>
</bean>
We have already configured authenticationManager and accessDecisionManager in previous parts.
Let us now configure mySecurityMetadataSource.
<bean id=" mySecurityMetadataSource" class="com.test.common.MySecurityMetadataSource">
<constructor-arg name="propHolder" ref="propHolder"/>
</bean>
Now let us write the bean MySecurityMetadataSource that extends MapBasedMethodSecurityMetadataSource.
Import org.springframework.security.access.method.MapBasedMethodSecurityMetadataSource;
public class MySecurityMetadataSource extends
MapBasedMethodSecurityMetadataSource {
public MyMethodSecurityFilterNew(PropertyHolder propHolder) {
super(propHolder.getMethodMap());
}
}
Now define the beans MyService in application context that we want to secure and define another bean org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator to create a proxy for MyService object so that an authorization check may be applied for every invocation on the object.
<bean id=”myService” class=”com.test.service.MyService” />
<bean id="autoProxyCreator" class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
<property name="interceptorNames">
<list>
<value>methodSecurityInterceptor</value>
</list>
</property>
<property name="beanNames">
<list>
<value> myService</value>
</list>
</property>
</bean>
Showing posts with label Spring Security 3. Show all posts
Showing posts with label Spring Security 3. Show all posts
Sunday, January 3, 2010
Spring Security – Part 2 – Custom securityMetadataSource
Now let us look into filterSecurityInterceptor. This filter authorizes web requests based on URL patterns. Instead of having the URLs configured in application context, we will have URLs in the properties file. We can even have these URLs configured in database or LDAP server. Here let us have properties file having URLs and the corresponding roles. The properties file looks like –
/admin/**=ROLE_ADMIN,ROLE_MANAGER
/admin/userPreference/**=ROLE_MANAGER
/admin/userPreference/updatePreference.action=ROLE_USER,ROLE_ASSOCIATE
/admin/userPreference/deletePreference.action=ROLE_USER
Here ROLE_ADMIN, ROLE_MANAGER are given complete access to all admin URLs, ROLE_MANAGER is given access to all URLs having /admin/userPreference/ and ROLE_USER, ROLE_ASSOCIATE are given page / action level access.
Now let us define filterSecurityInterceptor.
<bean id="filterSecurityInterceptor"
class="org.springframework.security.web.access.intercept.FilterSecurityInterceptor">
<property name="authenticationManager" ref="authenticationManager"/>
<property name="accessDecisionManager" ref="accessDecisionManager"/>
<property name="securityMetadataSource" ref="mySecureResourceFilter"/>
</bean>
We have already configured authenticationManager in the previous part. Let us now define accessDecisionManager.
<bean id="accessDecisionManager" class="org.springframework.security.access.vote.AffirmativeBased">
<property name="decisionVoters">
<list>
<bean class="org.springframework.security.access.vote.RoleVoter" />
<bean class="org.springframework.security.access.vote.AuthenticatedVoter" />
</list>
</property>
</bean>
We will look into it in more detail in next part.
Now let us write custom securityMetadataSource – mySecureResourceFilter
Let us define the bean first -
<bean id="mySecureResourceFilter" class="com.test.common.MySecureResourceFilter">
<property name="urlProperties">
<util:properties location="classpath:urls.properties" />
</property>
</bean>
Given the requested URL, we have to find all the roles authorized to access it. Like if requested URL is /admin/changePreference/deletePreference.action, we will get the roles from the properties file which can access the following URLs –
/admin/changePreference/deletePreference.action
/admin/changePreference/**
/admin/**
All this is implemented in getAttributes (..) method defined below which returns the name of the Authorities (or Roles) that are allowed to access requested URL.
import java.util.Collection;
import java.util.Properties;
import org.springframework.security.access.ConfigAttribute;
import org.springframework.security.access.SecurityConfig;
import org.springframework.security.web.FilterInvocation;
import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource;
public class MySecureResourceFilter implements
FilterInvocationSecurityMetadataSource {
private Properties urlProperties;
public Collection<ConfigAttribute> getAllConfigAttributes() {
return null;
}
public Collection<ConfigAttribute> getAttributes(Object filter)
throws IllegalArgumentException {
FilterInvocation filterInvocation = (FilterInvocation) filter;
String url = filterInvocation.getRequestUrl();
//get the roles for requested page from the property file
String urlPropsValue = urlProperties.getProperty(url);
StringBuilder rolesStringBuilder = new StringBuilder();
if(urlPropsValue != null) {
rolesStringBuilder.append(urlPropsValue).append(",");
}
if(!url.endsWith("/")) {
int lastSlashIndex = url.lastIndexOf("/");
url = url.substring(0, lastSlashIndex + 1);
}
String [] urlParts = url.split("/");
StringBuilder urlBuilder = new StringBuilder();
for (String urlPart : urlParts) {
if(urlPart.trim().length() == 0) {
continue;
}
urlBuilder.append("/").append(urlPart);
urlPropsValue = urlProperties.getProperty(urlBuilder.toString() + "/**");
if(urlPropsValue != null) {
rolesStringBuilder.append(urlPropsValue).append(",");
}
}
if(rolesStringBuilder.toString().endsWith(",")) {
rolesStringBuilder.deleteCharAt(rolesStringBuilder.length()-1);
}
if(rolesStringBuilder.length() == 0) {
return null;
}
return SecurityConfig.createListFromCommaDelimitedString(rolesStringBuilder.toString());
}
public boolean supports(Class<?> arg0) {
return true;
}
public void setUrlProperties(Properties urlProperties) {
this.urlProperties = urlProperties;
}
public Properties getUrlProperties() {
return urlProperties;
}
}
That’s it. In next part we will look into role based Method Invocation.
/admin/**=ROLE_ADMIN,ROLE_MANAGER
/admin/userPreference/**=ROLE_MANAGER
/admin/userPreference/updatePreference.action=ROLE_USER,ROLE_ASSOCIATE
/admin/userPreference/deletePreference.action=ROLE_USER
Here ROLE_ADMIN, ROLE_MANAGER are given complete access to all admin URLs, ROLE_MANAGER is given access to all URLs having /admin/userPreference/ and ROLE_USER, ROLE_ASSOCIATE are given page / action level access.
Now let us define filterSecurityInterceptor.
<bean id="filterSecurityInterceptor"
class="org.springframework.security.web.access.intercept.FilterSecurityInterceptor">
<property name="authenticationManager" ref="authenticationManager"/>
<property name="accessDecisionManager" ref="accessDecisionManager"/>
<property name="securityMetadataSource" ref="mySecureResourceFilter"/>
</bean>
We have already configured authenticationManager in the previous part. Let us now define accessDecisionManager.
<bean id="accessDecisionManager" class="org.springframework.security.access.vote.AffirmativeBased">
<property name="decisionVoters">
<list>
<bean class="org.springframework.security.access.vote.RoleVoter" />
<bean class="org.springframework.security.access.vote.AuthenticatedVoter" />
</list>
</property>
</bean>
We will look into it in more detail in next part.
Now let us write custom securityMetadataSource – mySecureResourceFilter
Let us define the bean first -
<bean id="mySecureResourceFilter" class="com.test.common.MySecureResourceFilter">
<property name="urlProperties">
<util:properties location="classpath:urls.properties" />
</property>
</bean>
Given the requested URL, we have to find all the roles authorized to access it. Like if requested URL is /admin/changePreference/deletePreference.action, we will get the roles from the properties file which can access the following URLs –
/admin/changePreference/deletePreference.action
/admin/changePreference/**
/admin/**
All this is implemented in getAttributes (..) method defined below which returns the name of the Authorities (or Roles) that are allowed to access requested URL.
import java.util.Collection;
import java.util.Properties;
import org.springframework.security.access.ConfigAttribute;
import org.springframework.security.access.SecurityConfig;
import org.springframework.security.web.FilterInvocation;
import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource;
public class MySecureResourceFilter implements
FilterInvocationSecurityMetadataSource {
private Properties urlProperties;
public Collection<ConfigAttribute> getAllConfigAttributes() {
return null;
}
public Collection<ConfigAttribute> getAttributes(Object filter)
throws IllegalArgumentException {
FilterInvocation filterInvocation = (FilterInvocation) filter;
String url = filterInvocation.getRequestUrl();
//get the roles for requested page from the property file
String urlPropsValue = urlProperties.getProperty(url);
StringBuilder rolesStringBuilder = new StringBuilder();
if(urlPropsValue != null) {
rolesStringBuilder.append(urlPropsValue).append(",");
}
if(!url.endsWith("/")) {
int lastSlashIndex = url.lastIndexOf("/");
url = url.substring(0, lastSlashIndex + 1);
}
String [] urlParts = url.split("/");
StringBuilder urlBuilder = new StringBuilder();
for (String urlPart : urlParts) {
if(urlPart.trim().length() == 0) {
continue;
}
urlBuilder.append("/").append(urlPart);
urlPropsValue = urlProperties.getProperty(urlBuilder.toString() + "/**");
if(urlPropsValue != null) {
rolesStringBuilder.append(urlPropsValue).append(",");
}
}
if(rolesStringBuilder.toString().endsWith(",")) {
rolesStringBuilder.deleteCharAt(rolesStringBuilder.length()-1);
}
if(rolesStringBuilder.length() == 0) {
return null;
}
return SecurityConfig.createListFromCommaDelimitedString(rolesStringBuilder.toString());
}
public boolean supports(Class<?> arg0) {
return true;
}
public void setUrlProperties(Properties urlProperties) {
this.urlProperties = urlProperties;
}
public Properties getUrlProperties() {
return urlProperties;
}
}
That’s it. In next part we will look into role based Method Invocation.
Saturday, January 2, 2010
Spring Security – Part 1 – Necessary Configuration and Custom UserDetailsService
Here we will look into –
1. The necessary configurations required
2. Write custom userDetailsService reading user name, password and roles from properties file
We will not use default security namespace configuration instead we will define beans and configure our own FilterChainProxy.
Add the schema declaration to the application context file –
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd"
xmlns:sec="http://www.springframework.org/schema/security"
xmlns:util="http://www.springframework.org/schema/util">
. . . . . .
</beans>
web.xml configuration
The first thing we need to do is add the following filter declaration to web.xml file:
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>
org.springframework.web.filter.DelegatingFilterProxy
</filter-class>
</filter>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
Now let us define and configure springSecurityFilterChain. It delegates request to a chain of Spring-managed filters. Since we would be customizing the Spring Security’s behavior we would be manually configuring the filters instead of using the default configuration.
For a web application we need to configure the following filters in the mentioned order –
1. HttpSessionContextIntegrationFilter – It queries HTTPSession to retrieve SecurityContext and populates SecurityContextHolder for the duration of web request. At the end of the web request, any updates made to the SecurityContextHolder will be persisted back to the HttpSession by this filter.
2. LogoutFilter – It clears SecurityContextHolder when logout is requested.
3. AuthenticationProcessingFilter – It puts Authentication into the SecurityContext on login request.
4. ExceptionTranslationFilter – It converts SpringSecurity exceptions into HTTP response or HTTP redirect.
5. FilterSecurityInterceptor – It authorizes web requests based on URL patterns.
Now let us define springSecurityFilterChain in application context file.
<bean id="springSecurityFilterChain" class="org.springframework.security.web.FilterChainProxy">
<sec:filter-chain-map path-type="ant">
<sec:filter-chain pattern="/**" filters=" httpSessionContextFilter,
logoutFilter,
authenticationProcessingFilter,
exceptionTranslationFilter,
filterSecurityInterceptor" />
</sec:filter-chain-map>
</bean>
Let us now configure the filters –
1. httpSessionContextFilter
Let us use the default configuration for httpSessionContextFilter.
<bean id="httpSessionContextFilter" class="org.springframework.security.web.context.HttpSessionContextIntegrationFilter"/>
2. exceptionTranslationFilter
It handles any AccessDeniedException and AuthenticationException thrown within the filter chain.
If an AuthenticationException is detected, the filter will launch the authenticationEntryPoint. If an AccessDeniedException is detected, the filter will determine whether or not the user is an anonymous user. If they are an anonymous user, the authenticationEntryPoint will be launched. If they are not an anonymous user, the filter will delegate to the AccessDeniedHandler.
Let us define the beans now. Login form url is set as “/login.jsp” for authenticationEntryPoint and error page is set as “/error/jsp” for access denied handler.
<bean id="exceptionTranslationFilter" class="org.springframework.security.web.access.ExceptionTranslationFilter">
<property name="authenticationEntryPoint" ref="authenticationEntryPoint"/>
<property name="accessDeniedHandler" ref="accessDeniedHandler" />
</bean>
<bean id="authenticationEntryPoint" class="org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint" >
<property name="loginFormUrl" value="/login.jsp" />
</bean>
<bean id="accessDeniedHandler" class="org.springframework.security.web.access.AccessDeniedHandlerImpl">
<property name="errorPage" value="/error401.jsp"/>
</bean>
3. authenticationProcessingFilter –
User information can be stored in database, in LDAP server or in properties file. Let us have user name, password and roles defined in a properties file (user.properties). We will write custom implementation of Spring Security's UserDetailsService - MyUserDetailService
user.properties has the following entries –
pranav=123123,ROLE_ADMIN
pranjal=321321,ROLE_MANAGER
sudheer=abcabc,ROLE_USER
Now let us write MyUserDetailService that implements UserDetailsService implementing method loadUserByUsername. This would load the user information from the user.properties creating UserDetails.
import java.util.Properties;
import org.springframework.dao.DataAccessException;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.core.userdetails.memory.UserAttribute;
import org.springframework.security.core.userdetails.memory.UserAttributeEditor;
public class MyUserDetailService implements UserDetailsService {
private Properties userProperties;
public UserDetails loadUserByUsername(String username)
throws UsernameNotFoundException, DataAccessException {
String userPropsValue = userProperties.getProperty(username);
if (userPropsValue == null) {
throw new UsernameNotFoundException(username
+ "User does not exist");
}
UserAttributeEditor configAttribEd = new UserAttributeEditor();
configAttribEd.setAsText(userPropsValue);
UserAttribute userAttributes = (UserAttribute) configAttribEd
.getValue();
return new User(username, userAttributes.getPassword(), userAttributes
.isEnabled(), true, true, true, userAttributes.getAuthorities());
}
public void setUserProperties(Properties userProperties) {
this.userProperties = userProperties;
}
public Properties getUserProperties() {
return userProperties;
}
}
Now let us define the beans. Post successful authentication user would be shown the requested URL or the default target url “/home.action” set to authenticationSuccessHandler.
<bean id="authenticationProcessingFilter" class="org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter">
<property name="authenticationManager" ref="authenticationManager" />
<property name="authenticationSuccessHandler" ref="authenticationSuccessHandler"/>
</bean>
<bean id="authenticationManager" class="org.springframework.security.authentication.ProviderManager">
<property name="providers">
<list>
<ref bean="authenticationProvider"/>
</list>
</property>
</bean>
<bean id="authenticationProvider" class="org.springframework.security.authentication.dao.DaoAuthenticationProvider">
<property name="userDetailsService" ref="userDetailService"/>
</bean>
<bean id="userDetailService" class="com.test.common.MyUserDetailService">
<property name="userProperties">
<util:properties location="classpath:users.properties" />
</property>
</bean>
<bean id="authenticationSuccessHandler" class="org.springframework.security.web.authentication.SimpleUrlAuthenticationSuccessHandler">
<property name="defaultTargetUrl" value="/home.action"/>
</bean>
We will look into filterSecurityInterceptor and logoutFilter in next part.
1. The necessary configurations required
2. Write custom userDetailsService reading user name, password and roles from properties file
We will not use default security namespace configuration instead we will define beans and configure our own FilterChainProxy.
Add the schema declaration to the application context file –
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd"
xmlns:sec="http://www.springframework.org/schema/security"
xmlns:util="http://www.springframework.org/schema/util">
. . . . . .
</beans>
web.xml configuration
The first thing we need to do is add the following filter declaration to web.xml file:
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>
org.springframework.web.filter.DelegatingFilterProxy
</filter-class>
</filter>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
Now let us define and configure springSecurityFilterChain. It delegates request to a chain of Spring-managed filters. Since we would be customizing the Spring Security’s behavior we would be manually configuring the filters instead of using the default configuration.
For a web application we need to configure the following filters in the mentioned order –
1. HttpSessionContextIntegrationFilter – It queries HTTPSession to retrieve SecurityContext and populates SecurityContextHolder for the duration of web request. At the end of the web request, any updates made to the SecurityContextHolder will be persisted back to the HttpSession by this filter.
2. LogoutFilter – It clears SecurityContextHolder when logout is requested.
3. AuthenticationProcessingFilter – It puts Authentication into the SecurityContext on login request.
4. ExceptionTranslationFilter – It converts SpringSecurity exceptions into HTTP response or HTTP redirect.
5. FilterSecurityInterceptor – It authorizes web requests based on URL patterns.
Now let us define springSecurityFilterChain in application context file.
<bean id="springSecurityFilterChain" class="org.springframework.security.web.FilterChainProxy">
<sec:filter-chain-map path-type="ant">
<sec:filter-chain pattern="/**" filters=" httpSessionContextFilter,
logoutFilter,
authenticationProcessingFilter,
exceptionTranslationFilter,
filterSecurityInterceptor" />
</sec:filter-chain-map>
</bean>
Let us now configure the filters –
1. httpSessionContextFilter
Let us use the default configuration for httpSessionContextFilter.
<bean id="httpSessionContextFilter" class="org.springframework.security.web.context.HttpSessionContextIntegrationFilter"/>
2. exceptionTranslationFilter
It handles any AccessDeniedException and AuthenticationException thrown within the filter chain.
If an AuthenticationException is detected, the filter will launch the authenticationEntryPoint. If an AccessDeniedException is detected, the filter will determine whether or not the user is an anonymous user. If they are an anonymous user, the authenticationEntryPoint will be launched. If they are not an anonymous user, the filter will delegate to the AccessDeniedHandler.
Let us define the beans now. Login form url is set as “/login.jsp” for authenticationEntryPoint and error page is set as “/error/jsp” for access denied handler.
<bean id="exceptionTranslationFilter" class="org.springframework.security.web.access.ExceptionTranslationFilter">
<property name="authenticationEntryPoint" ref="authenticationEntryPoint"/>
<property name="accessDeniedHandler" ref="accessDeniedHandler" />
</bean>
<bean id="authenticationEntryPoint" class="org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint" >
<property name="loginFormUrl" value="/login.jsp" />
</bean>
<bean id="accessDeniedHandler" class="org.springframework.security.web.access.AccessDeniedHandlerImpl">
<property name="errorPage" value="/error401.jsp"/>
</bean>
3. authenticationProcessingFilter –
User information can be stored in database, in LDAP server or in properties file. Let us have user name, password and roles defined in a properties file (user.properties). We will write custom implementation of Spring Security's UserDetailsService - MyUserDetailService
user.properties has the following entries –
pranav=123123,ROLE_ADMIN
pranjal=321321,ROLE_MANAGER
sudheer=abcabc,ROLE_USER
Now let us write MyUserDetailService that implements UserDetailsService implementing method loadUserByUsername. This would load the user information from the user.properties creating UserDetails.
import java.util.Properties;
import org.springframework.dao.DataAccessException;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.core.userdetails.memory.UserAttribute;
import org.springframework.security.core.userdetails.memory.UserAttributeEditor;
public class MyUserDetailService implements UserDetailsService {
private Properties userProperties;
public UserDetails loadUserByUsername(String username)
throws UsernameNotFoundException, DataAccessException {
String userPropsValue = userProperties.getProperty(username);
if (userPropsValue == null) {
throw new UsernameNotFoundException(username
+ "User does not exist");
}
UserAttributeEditor configAttribEd = new UserAttributeEditor();
configAttribEd.setAsText(userPropsValue);
UserAttribute userAttributes = (UserAttribute) configAttribEd
.getValue();
return new User(username, userAttributes.getPassword(), userAttributes
.isEnabled(), true, true, true, userAttributes.getAuthorities());
}
public void setUserProperties(Properties userProperties) {
this.userProperties = userProperties;
}
public Properties getUserProperties() {
return userProperties;
}
}
Now let us define the beans. Post successful authentication user would be shown the requested URL or the default target url “/home.action” set to authenticationSuccessHandler.
<bean id="authenticationProcessingFilter" class="org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter">
<property name="authenticationManager" ref="authenticationManager" />
<property name="authenticationSuccessHandler" ref="authenticationSuccessHandler"/>
</bean>
<bean id="authenticationManager" class="org.springframework.security.authentication.ProviderManager">
<property name="providers">
<list>
<ref bean="authenticationProvider"/>
</list>
</property>
</bean>
<bean id="authenticationProvider" class="org.springframework.security.authentication.dao.DaoAuthenticationProvider">
<property name="userDetailsService" ref="userDetailService"/>
</bean>
<bean id="userDetailService" class="com.test.common.MyUserDetailService">
<property name="userProperties">
<util:properties location="classpath:users.properties" />
</property>
</bean>
<bean id="authenticationSuccessHandler" class="org.springframework.security.web.authentication.SimpleUrlAuthenticationSuccessHandler">
<property name="defaultTargetUrl" value="/home.action"/>
</bean>
We will look into filterSecurityInterceptor and logoutFilter in next part.
Subscribe to:
Posts (Atom)