听说springsecurity功能很强大,昨天小运行了个例子,贴出来与大家分享。
联系方式QQ:263090670
关于配置:
1 )在 web.xml 中添加红色部分,引入spring安全框架
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<display-name>ab</display-name>
<!-- Spring ApplicationContext配置文件的路径,可使用通配符,多个路径用,号分隔
此参数用于后面的Spring Context Loader -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
classpath*:/applicationContext.xml
classpath*:/applicationContext-security.xml
</param-value>
</context-param>
<!-- Filter 定义 -->
<!-- Character Encoding filter -->
<filter>
<filter-name>encodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
<init-param>
<param-name>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<!-- Hibernate Open Session In View filter-->
<filter>
<filter-name>hibernateOpenSessionInViewFilter</filter-name>
<filter-class>org.springframework.orm.hibernate3.support.OpenSessionInViewFilter</filter-class>
</filter>
<!-- SpringSecurity filter-->
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<!-- Struts2 filter -->
<filter>
<filter-name>struts2CleanupFilter</filter-name>
<filter-class>org.apache.struts2.dispatcher.ActionContextCleanUp</filter-class>
</filter>
<filter>
<filter-name>struts2Filter</filter-name>
<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
</filter>
<!-- Filter 映射 -->
<filter-mapping>
<filter-name>encodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>hibernateOpenSessionInViewFilter</filter-name>
<url-pattern>*.action</url-pattern>
<dispatcher>REQUEST</dispatcher>
<dispatcher>FORWARD</dispatcher>
</filter-mapping>
<filter-mapping>
<filter-name>hibernateOpenSessionInViewFilter</filter-name>
<url-pattern>/j_spring_security_check</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>REQUEST</dispatcher>
<dispatcher>FORWARD</dispatcher>
</filter-mapping>
<filter-mapping>
<filter-name>struts2CleanupFilter</filter-name>
<url-pattern>*.action</url-pattern>
<dispatcher>REQUEST</dispatcher>
<dispatcher>FORWARD</dispatcher>
</filter-mapping>
<filter-mapping>
<filter-name>struts2Filter</filter-name>
<url-pattern>*.action</url-pattern>
<dispatcher>REQUEST</dispatcher>
<dispatcher>FORWARD</dispatcher>
</filter-mapping>
<!--Spring的ApplicationContext 载入 -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- Spring 刷新Introspector防止内存泄露 -->
<listener>
<listener-class>org.springframework.web.util.IntrospectorCleanupListener</listener-class>
</listener>
<!-- session超时定义,单位为分钟 -->
<session-config>
<session-timeout>20</session-timeout>
</session-config>
<!-- 出错页面定义 -->
<error-page>
<exception-type>java.lang.Throwable</exception-type>
<location>/common/500.jsp</location>
</error-page>
<error-page>
<error-code>500</error-code>
<location>/common/500.jsp</location>
</error-page>
<error-page>
<error-code>404</error-code>
<location>/common/404.jsp</location>
</error-page>
<error-page>
<error-code>403</error-code>
<location>/common/403.jsp</location>
</error-page>
</web-app>
2)applicationContext-security.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:s="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/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.0.xsd"
default-lazy-init="true">
<description>SpringSecurity安全配置</description>
<bean id="myFilter" class="org.springframework.security.web.access.intercept.FilterSecurityInterceptor">
<property name="authenticationManager" ref="authenticationManager"></property>
<property name="accessDecisionManager">
<bean class="org.springframework.security.access.vote.AffirmativeBased">
<property name="decisionVoters">
<list>
<bean class="org.springframework.security.access.vote.RoleVoter"></bean>
</list>
</property>
</bean>
</property>
<property name="securityMetadataSource" ref="resourceService"></property>
</bean>
<!-- http安全配置 -->
<s:http auto-config="true" use-expressions="true">
<s:intercept-url pattern="/css/**" filters="none" />
<s:intercept-url pattern="/img/**" filters="none" />
<s:intercept-url pattern="/js/**" filters="none" />
<!--
<s:intercept-url pattern="/account/user!save*" access="hasAnyRole('ROLE_修改用户')" />
<s:intercept-url pattern="/account/user!delete*" access="hasAnyRole('ROLE_修改用户')" />
<s:intercept-url pattern="/account/user*" access="hasAnyRole('ROLE_浏览用户')" />
<s:intercept-url pattern="/account/role!save*" access="hasAnyRole('ROLE_修改角色')" />
<s:intercept-url pattern="/account/role!delete*" access="hasAnyRole('ROLE_修改角色')" />
<s:intercept-url pattern="/account/role*" access="hasAnyRole('ROLE_浏览角色')" />
-->
<!-- 下面红色部分说明 ref="myFilter" 自定义返回配置 等同于 <s:intercept-url pattern="/account/role*" access="hasAnyRole('ROLE_浏览角色')" />
-->
<s:custom-filter ref="myFilter" before="FILTER_SECURITY_INTERCEPTOR"/>
<s:form-login login-page="/login.action" default-target-url="/" authentication-failure-url="/login.action?error=true" />
<s:logout logout-success-url="/" />
</s:http>
<!-- 认证配置, 使用userDetailsService提供的用户信息 -->
<s:authentication-manager alias="authenticationManager">
<s:authentication-provider user-service-ref="userDetailsService">
<s:password-encoder hash="plaintext" />
</s:authentication-provider>
</s:authentication-manager>
<!-- 项目实现的用户查询服务 -->
<bean id="userDetailsService" class="com.service.account.UserDetailsServiceImpl" />
</beans>
3)applicationContext.xml中添加配置
<bean id="resourceService" class="com.service.account.ResourceServiceImp"/>
关于自定义类:
1)UserDetailsServiceImpl.java
说明:loadUserByUsername 为核心方法 返回自定义验证信息。
package com.service.account;
import java.util.Set;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.GrantedAuthorityImpl;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.transaction.annotation.Transactional;
import com.entity.account.Authority;
import com.entity.account.Role;
import com.entity.account.User;
import com.google.common.collect.Sets;
/**
* 实现SpringSecurity的UserDetailsService接口,实现获取用户Detail信息的回调函数.
*
* @author calvin
*/
@Transactional(readOnly = true)
public class UserDetailsServiceImpl implements UserDetailsService {
private AccountManager accountManager;
/**
* 获取用户Details信息的回调函数.
*/
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException, DataAccessException {
User user = accountManager.findUserByLoginName(username);
if (user == null) {
throw new UsernameNotFoundException("用户" + username + " 不存在");
}
Set<GrantedAuthority> grantedAuths = obtainGrantedAuthorities(user);
Set<GrantedAuthority> grantedAuths1=Sets.newHashSet();
grantedAuths1.add(new GrantedAuthorityImpl("ROLE_浏览角色"));
//-- jcs示例中无以下属性, 暂时全部设为true. --//
boolean enabled = true;
boolean accountNonExpired = true;
boolean credentialsNonExpired = true;
boolean accountNonLocked = true;
UserDetails userdetails = new org.springframework.security.core.userdetails.User(user.getLoginName(), user
.getPassword(), enabled, accountNonExpired, credentialsNonExpired, accountNonLocked, grantedAuths);
return userdetails;
}
/**
* 获得用户所有角色的权限集合.
*/
private Set<GrantedAuthority> obtainGrantedAuthorities(User user) {
Set<GrantedAuthority> authSet = Sets.newHashSet();
for (Role role : user.getRoleList()) {
for (Authority authority : role.getAuthorityList()) {
authSet.add(new GrantedAuthorityImpl(authority.getPrefixedName()));
}
}
return authSet;
}
@Autowired
public void setAccountManager(AccountManager accountManager) {
this.accountManager = accountManager;
}
}
2)ResourceServiceImp.java 自定义配置信息
package com.service.account;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import org.springframework.security.access.ConfigAttribute;
import org.springframework.security.access.SecurityConfig;
import org.springframework.security.web.FilterInvocation;
import org.springframework.security.web.util.AntUrlPathMatcher;
import org.springframework.security.web.util.UrlMatcher;
public class ResourceServiceImp implements ResourceService{
@Override
public boolean supports(Class<?> arg0) {
// TODO Auto-generated method stub
return true;
}
@Override
public Collection<ConfigAttribute> getAllConfigAttributes() {
Set<ConfigAttribute> AllConfigAttributes=new HashSet<ConfigAttribute>();
AllConfigAttributes.add(new SecurityConfig("ROLE_修改用户"));
AllConfigAttributes.add(new SecurityConfig("ROLE_修改用户"));
AllConfigAttributes.add(new SecurityConfig("ROLE_浏览用户"));
AllConfigAttributes.add(new SecurityConfig("ROLE_修改角色"));
AllConfigAttributes.add(new SecurityConfig("ROLE_修改角色"));
AllConfigAttributes.add(new SecurityConfig("ROLE_浏览角色"));
return AllConfigAttributes;
}
//核心代码
@Override
public Collection<ConfigAttribute> getAttributes(Object object)
throws IllegalArgumentException {
Map<String,Collection<ConfigAttribute>> resourceMap=new HashMap<String,Collection<ConfigAttribute>>();
Collection<ConfigAttribute> collection3=new ArrayList<ConfigAttribute>();
collection3.add(new SecurityConfig("ROLE_浏览用户"));
Collection<ConfigAttribute> collection4=new ArrayList<ConfigAttribute>();
collection4.add(new SecurityConfig("ROLE_浏览角色"));
Collection<ConfigAttribute> collection1=new ArrayList<ConfigAttribute>();
collection1.add(new SecurityConfig("ROLE_修改角色"));
//collection1.add(new SecurityConfig("ROLE_浏览角色"));
//collection1.add(new SecurityConfig("ROLE_查看角色"));
Collection<ConfigAttribute> collection=new ArrayList<ConfigAttribute>();
collection.add(new SecurityConfig("ROLE_修改用户"));
//collection.add(new SecurityConfig("ROLE_浏览用户"));
//collection.add(new SecurityConfig("ROLE_查看用户"));
resourceMap.put("/account/user!save*", collection);
resourceMap.put("/account/user!delete*", collection);
resourceMap.put("/account/user*", collection3);
resourceMap.put("/account/role!save*", collection1);
resourceMap.put("/account/role!delete*", collection1);
resourceMap.put("/account/role*", collection4);
FilterInvocation filterInvocation=(FilterInvocation)object;
String url=filterInvocation.getRequestUrl();
UrlMatcher urlMatcher=new AntUrlPathMatcher();
Iterator it=resourceMap.keySet().iterator();
System.out.println("url:"+url);
while(it.hasNext()){
String reqUrl=(String)it.next();
if(urlMatcher.pathMatchesUrl(reqUrl, url)){
Collection<ConfigAttribute> collectionReturn=resourceMap.get(reqUrl);
return collectionReturn;
};
}
return null;
}
}
3)ResourceService.java 自定义配置信息
package com.service.account;
import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource;
public interface ResourceService extends FilterInvocationSecurityMetadataSource {
}