<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-core</artifactId>
<version>3.1.3.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-web</artifactId>
<version>3.1.3.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-config</artifactId>
<version>3.1.3.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-taglibs</artifactId>
<version>3.1.3.RELEASE</version>
</dependency>
2、在web.xml中加入Spring Security的過濾器:
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring-*.xml,classpath:beans.xml</param-value>
</context-param>
<!-- 用於初始化 Sping Security 的 filterChain -->
<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>
3、Spring Security的配置:
<?xml version="1.0" encoding="UTF-8"?>
<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.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.1.xsd">
<http pattern="/adminLogin.action" security="none"/>
<http pattern="/adminLoginSubmit.action" security="none"/>
<http pattern="/static/**" security="none"/>
<http auto-config="true" use-expressions="true">
<form-login login-page="/adminLogin.action"
authentication-failure-url="/adminLogin.action?error=true "/>
<logout logout-success-url="/adminLogin.action"
invalidate-session="true" />
<session-management invalid-session-url="/adminLogin.action">
<concurrency-control max-sessions="1" />
</session-management>
<custom-filter ref="myFilter" before="FILTER_SECURITY_INTERCEPTOR"/>
</http>
<beans:bean id="myFilter" class="com.sz7road.web.security.MyFilterSecurityInterceptor">
<beans:property name="accessDecisionManager" ref="myAccessDecisionManager" /><!-- 資源訪問決策 -->
<beans:property name="authenticationManager" ref="authenticationManager" /><!-- 登陸的認證 -->
<beans:property name="securityMetadataSource" ref="mySecurityMetadataSource" /><!-- 資源和權限列表 -->
</beans:bean>
<authentication-manager alias="authenticationManager">
<authentication-provider user-service-ref="userDetailsService">
</authentication-provider>
</authentication-manager>
<beans:bean name="userDetailsService" class="com.sz7road.web.security.MyUserDetailsService">
</beans:bean>
<beans:bean name="myAccessDecisionManager" class="com.sz7road.web.security.MyAccessDecisionManager">
</beans:bean>
<beans:bean name="mySecurityMetadataSource" class="com.sz7road.web.security.MyInvocationSecurityMetadataSourceService">
</beans:bean>
</beans:beans>
4、四個主要類的實現:
package com.sz7road.web.security;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import javax.annotation.Resource;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.GrantedAuthorityImpl;
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 com.sz7road.web.dao.UserDao;
import com.sz7road.web.model.user.User;
public class MyUserDetailsService implements UserDetailsService{
@Resource
private UserDao userDao;
@Override
public UserDetails loadUserByUsername(String username)
throws UsernameNotFoundException {
Collection<GrantedAuthority> auths = new ArrayList<GrantedAuthority>();
User user = new User();
try {
user = userDao.getUserByName(username);
List<String> authStr= userDao.loadUserAuthoritiesByName(username);
for (String authName : authStr) {
SimpleGrantedAuthority authority = new SimpleGrantedAuthority(authName);
auths.add(authority);
}
} catch (Exception e) {
e.printStackTrace();
}
return new User(user.getId(), user.getUserName(), user.getPassword(), user.getEmail(), user.getCreateDate(), user.getUserName(), auths, true, true, true);
}
}
package com.sz7road.web.security;
import java.util.Collection;
import java.util.Iterator;
import org.springframework.security.access.AccessDecisionManager;
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 MyAccessDecisionManager implements AccessDecisionManager {
@Override
public void decide(Authentication authentication, Object object,
Collection<ConfigAttribute> configAttributes)
throws AccessDeniedException, InsufficientAuthenticationException {
if( configAttributes == null ) {
return ;
}
Iterator<ConfigAttribute> ite = configAttributes.iterator();
while( ite.hasNext()){
ConfigAttribute ca = ite.next();
String needRole = ((SecurityConfig)ca).getAttribute();
for( GrantedAuthority ga: authentication.getAuthorities()){
if(needRole.trim().equals(ga.getAuthority().trim())){
return;
}
}
}
throw new AccessDeniedException("無權限!");
}
@Override
public boolean supports(ConfigAttribute attribute) {
return true;
}
@Override
public boolean supports(Class<?> clazz) {
return true;
}
}
package com.sz7road.web.security;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import javax.annotation.Resource;
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 com.sz7road.web.dao.PermissionDao;
import com.sz7road.web.model.permission.Permission;
public class MyInvocationSecurityMetadataSourceService implements
FilterInvocationSecurityMetadataSource {
@Resource
private PermissionDao permDao;
@Override
public Collection<ConfigAttribute> getAttributes(Object object)
throws IllegalArgumentException {
String url = ((FilterInvocation) object).getRequestUrl();
int firstQuestionMarkIndex = url.indexOf("?");
if (firstQuestionMarkIndex != -1) {
url = url.substring(0, firstQuestionMarkIndex);
}
if (firstQuestionMarkIndex != -1) {
url = url.substring(0, firstQuestionMarkIndex);
}
System.out.println("url:"+url);
List<ConfigAttribute> result = new ArrayList<ConfigAttribute>();
ConfigAttribute attribute = new SecurityConfig("ROLE_BASE");
result.add(attribute);
try {
List<Permission> permList = permDao.getPermissionByUrl(url);
for (Permission permission : permList) {
ConfigAttribute conf = new SecurityConfig(permission.getPermName());
result.add(conf);
}
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
@Override
public Collection<ConfigAttribute> getAllConfigAttributes() {
// TODO Auto-generated method stub
return null;
}
@Override
public boolean supports(Class<?> clazz) {
// TODO Auto-generated method stub
return true;
}
}
package com.sz7road.web.security;
import java.io.IOException;
import java.util.Collection;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import org.springframework.security.access.ConfigAttribute;
import org.springframework.security.access.SecurityMetadataSource;
import org.springframework.security.access.intercept.AbstractSecurityInterceptor;
import org.springframework.security.access.intercept.InterceptorStatusToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.FilterInvocation;
import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource;
public class MyFilterSecurityInterceptor extends AbstractSecurityInterceptor
implements Filter {
private FilterInvocationSecurityMetadataSource securityMetadataSource;
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
FilterInvocation fi = new FilterInvocation(request, response, chain);
invoke(fi);
}
@Override
public void destroy() {
}
@Override
public Class<?> getSecureObjectClass() {
return FilterInvocation.class;
}
@Override
public SecurityMetadataSource obtainSecurityMetadataSource() {
return this.securityMetadataSource;
}
public FilterInvocationSecurityMetadataSource getSecurityMetadataSource() {
return this.securityMetadataSource;
}
public void invoke(FilterInvocation fi) throws IOException,
ServletException {
InterceptorStatusToken token = super.beforeInvocation(fi);
try {
fi.getChain().doFilter(fi.getRequest(), fi.getResponse());
} finally {
super.afterInvocation(token, null);
}
}
public void setSecurityMetadataSource(
FilterInvocationSecurityMetadataSource securityMetadataSource) {
this.securityMetadataSource = securityMetadataSource;
}
}