说到权限系统,几乎每个系统都要用到,只要涉及到人操作和管理的的系统。而权限系统的核心那就是:授权和认证。 大道至简,根据这个核心所有的第三方还是适合自己的权限系统都围绕此进行。 Spring Security 也是如此,在系统中怎样接入Spring Security呢?主要有以下几步: 1、配置文件 <beans:beans xmlns="http://www.springframework.org/schema/security" xmlns:beans="http://www.springframework.org/schema/beans" 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.spr ingframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.1.xsd"> <http> <intercept-url pattern="/login.htm" access="IS_AUTHENTICATED_ANONYMOUSLY" /> <form-login login-page="/login.htm" login-processing-url="/login_process.htm" authentication-failure-url="/login.htm?error=true" default-target-url="/index.htm" password-parameter="password" username-parameter="username" /> <http-basic /> <logout logout-success-url="/login.htm" logout-url="/logout.htm"/> <remember-me token-validity-seconds="604800" /> <!-- 1 week --> <custom-filter ref="resourceSecurityInterceptor" before="FILTER_SECURITY_INTERCEPTOR"/> </http> <authentication-manager alias="authenticationManager"> <authentication-provider user-service-ref="securityManager"> <password-encoder hash="md5"/> </authentication-provider> </authentication-manager> <beans:bean id="securityManager" class="com.apache.platform.service.authorization.SecurityManagerSupport"></beans:bean> <beans:bean id="resourceSecurityInterceptor" class="org.springframework.security.web.access.intercept.FilterSecurityInterceptor"> <!-- 认证管理 --> <beans:property name="authenticationManager" ref="authenticationManager"/> <!-- 访问决策 --> <beans:property name="accessDecisionManager" ref="accessDecisionManager"/> <!-- 资源定义 --> <beans:property name="securityMetadataSource" ref="secureResourceFilterInvocationDefinitionSource" /> </beans:bean> <!-- 访问决策器 --> <beans:bean id="accessDecisionManager" class="com.apache.platform.service.authorization.AccessDecisionManager"> </beans:bean> <beans:bean id="secureResourceFilterInvocationDefinitionSource" class="com.apache.platform.service.authorization.SecureResourceFilterInvocationDefinitionSource" /> </beans:beans> 整个权限系统的接入围绕这个配置文件展开。 1》 认证管理 主要提供用户登录访问认证操作 2》 访问决策 对资源访问定义规则和策略 3》 资源定义 根据认证用户加载访问资源 SecurityManagerSupport.java /** * */ package com.apache.platform.service.authorization; import java.util.ArrayList; import java.util.Collection; import javax.servlet.ServletContext; import org.apache.commons.lang.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.authority.SimpleGrantedAuthority; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.core.userdetails.UsernameNotFoundException; import org.springframework.web.context.ServletContextAware; import com.apache.platform.common.CommConstant; import com.apache.platform.service.IUserManager; /** * @author tangss * @2013年9月28日 @上午9:19:25 */ public class SecurityManagerSupport implements UserDetailsService, ServletContextAware { @Autowired private IUserManager userManager; ServletContext servletContext; @Override public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { UserDetails user = null; if (StringUtils.isNotEmpty(username) && username.equals("test")) { Collection<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>(); authorities.add(new SimpleGrantedAuthority("admin_role")); user = new UserInfo(username, "e10adc3949ba59abbe56e057f20f883e", true, true, true, true, authorities); } else { user = userManager.getUserByUserName(username); } this.servletContext.setAttribute(CommConstant.USER_INFO, user); return user; } /* * (non-Javadoc) * @see org.springframework.web.context.ServletContextAware#setServletContext(javax.servlet.ServletContext) */ @Override public void setServletContext(ServletContext servletContext) { this.servletContext = servletContext; } } AccessDecisionManager.java package com.apache.platform.service.authorization; import java.util.Collection; import org.springframework.security.access.AccessDeniedException; import org.springframework.security.access.ConfigAttribute; import org.springframework.security.access.SecurityConfig; import org.springframework.security.authentication.InsufficientAuthenticationException; import org.springframework.security.core.Authentication; import org.springframework.security.core.GrantedAuthority; /** * * */ public class AccessDecisionManager implements org.springframework.security.access.AccessDecisionManager { @Override public void decide(Authentication authentication, Object object, Collection<ConfigAttribute> configAttributes) throws AccessDeniedException, InsufficientAuthenticationException { if (configAttributes == null) { return; } for (ConfigAttribute ca : configAttributes) { String needRole = ((SecurityConfig) ca).getAttribute(); for (GrantedAuthority ga : authentication.getAuthorities()) { if (needRole.equals(ga.getAuthority())) { return; } } } throw new AccessDeniedException("没有权限"); } @Override public boolean supports(ConfigAttribute attribute) { return true; } @Override public boolean supports(Class<?> clazz) { return true; } } SecureResourceFilterInvocationDefinitionSource.java /** * */ package com.apache.platform.service.authorization; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.Map; import java.util.Map.Entry; import java.util.Set; import javax.servlet.ServletContext; 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; import org.springframework.security.web.util.AntPathRequestMatcher; import org.springframework.security.web.util.RequestMatcher; import org.springframework.web.context.ServletContextAware; import com.apache.platform.common.CommConstant; /** * @author tangss * @2013年9月28日 @上午9:44:38 */ public class SecureResourceFilterInvocationDefinitionSource implements FilterInvocationSecurityMetadataSource, ServletContextAware { private Map<String, String> linkMap; private Map<String, Collection<ConfigAttribute>> resourceMap = new HashMap<String, Collection<ConfigAttribute>>(); // 获得请求资源所需的权限 @Override public Collection<ConfigAttribute> getAttributes(Object filter) throws IllegalArgumentException { if (linkMap == null || linkMap.isEmpty()) { return null; } RequestMatcher matcher = null; Set<Entry<String, String>> linkSet = linkMap.entrySet(); for (Entry<String, String> entry : linkSet) { String url = entry.getKey(); matcher = new AntPathRequestMatcher(url); if (matcher.matches(((FilterInvocation) filter).getRequest())) { Collection<ConfigAttribute> configAttributes = resourceMap.get(url); if (configAttributes != null) { return configAttributes; } // 解析 role String value = entry.getValue(); // split by comma String values[] = value.split(","); configAttributes = new ArrayList<ConfigAttribute>(); for (String attribute : values) { ConfigAttribute configAttribute = new SecurityConfig(attribute); configAttributes.add(configAttribute); } resourceMap.put(url, configAttributes); return configAttributes; } } return null; } @Override public Collection<ConfigAttribute> getAllConfigAttributes() { return null; } @Override public boolean supports(Class<?> clazz) { return true; } @SuppressWarnings("unchecked") @Override public void setServletContext(ServletContext servletContext) { linkMap = (Map<String, String>) servletContext.getAttribute(CommConstant.LINK_MAP); } } 2、登录页面 #set($layout = "/layout/blankLayout.vm") <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html;charset=utf-8" /> <title>登录</title> <script type="text/javascript" src="$!{scriptsPath}scripts/common/jquery-1.10.2.js"></script> <link rel="stylesheet" type="text/css" href="$!{stylesPath}styles/login.css" /> </head> <body> <form method="post" action="login_process.htm"> <div class="login"> <p> 用户名:<input type="text" name="username" /> <p> 密 码:<input type="password" name="password" /> </p> </p> <p> <input type="checkbox" name="_spring_security_remember_me" /> 记住我 </p> <p> <input type="submit" value="登 录" class="btn" /> </p> </div> </form> </body> </html> 3 、web.mxl 配置 <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>*.htm</url-pattern> </filter-mapping> 4、maven pom.xml <dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-web</artifactId> <version>3.1.4.RELEASE</version> </dependency> <dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-config</artifactId> <version>3.1.4.RELEASE</version> </dependency>