spring security 登录、权限管理配置
登录流程
1)容器启动(MySecurityMetadataSource:loadResourceDefine加载系统资源与权限列表)
2)用户发出请求
3)过滤器拦截(MySecurityFilter:doFilter)
4)取得请求资源所需权限(MySecurityMetadataSource:getAttributes)
5)匹配用户拥有权限和请求权限(MyAccessDecisionManager:decide),如果用户没有相应的权限,
执行第6步,否则执行第7步。
6)登录
7)验证并授权(MyUserDetailServiceImpl:loadUserByUsername)
1、web.xml中加入过滤器
- <!-- SpringSecurity 核心过滤器配置 -->
- <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>
<!-- SpringSecurity 核心过滤器配置 -->
<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>
2、新建spring-security.xml文件
- <?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.xsd
- http://www.springframework.org/schema/security
- http://www.springframework.org/schema/security/spring-security.xsd">
- <!-- entry-point-ref 配置自定义登录 -->
- <http use-expressions="true" entry-point-ref="authenticationProcessingFilterEntryPoint">
- <!-- 登出配置 -->
- <logout logout-url="/j_spring_security_logout" logout-success-url="/login" />
- <access-denied-handler error-page="/noPower" />
- <!-- 过滤不被拦截的请求 -->
- <intercept-url pattern="/login*" access="permitAll" />
- <intercept-url pattern="/resources/**" access="permitAll" />
- <!-- 只有权限才能访问的请求 -->
- <intercept-url pattern="/admin/**" access="isAuthenticated()" />
- <custom-filter ref="loginFilter" position="FORM_LOGIN_FILTER" />
- <custom-filter ref="securityFilter" before="FILTER_SECURITY_INTERCEPTOR" />
- </http>
- <beans:bean id="loginFilter"
- class="cn.com.abel.test.service.security.MyUsernamePasswordAuthenticationFilter">
- <!-- 登录提交处理 -->
- <beans:property name="filterProcessesUrl" value="/j_spring_security_check"></beans:property>
- <!-- 登录成功跳转 -->
- <beans:property name="authenticationSuccessHandler"
- ref="loginLogAuthenticationSuccessHandler"></beans:property>
- <!-- 设置登录失败的网址 -->
- <beans:property name="authenticationFailureHandler"
- ref="simpleUrlAuthenticationFailureHandler"></beans:property>
- <!-- 用户拥有权限 -->
- <beans:property name="authenticationManager" ref="myAuthenticationManager"></beans:property>
- </beans:bean>
- <beans:bean id="loginLogAuthenticationSuccessHandler"
- class="org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler">
- <beans:property name="defaultTargetUrl" value="/admin/index"></beans:property>
- </beans:bean>
- <beans:bean id="simpleUrlAuthenticationFailureHandler"
- class="org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler">
- <beans:property name="defaultFailureUrl" value="/login"></beans:property>
- </beans:bean>
- <authentication-manager alias="myAuthenticationManager">
- <authentication-provider user-service-ref="myUserDetailServiceImpl">
- <password-encoder ref="encoder" />
- </authentication-provider>
- </authentication-manager>
- <beans:bean id="myUserDetailServiceImpl"
- class="cn.com.abel.test.service.security.AdminUserDetailServiceImpl">
- </beans:bean>
- <beans:bean id="authenticationProcessingFilterEntryPoint"
- class="org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint">
- <beans:property name="loginFormUrl" value="/login"></beans:property>
- </beans:bean>
- <!-- 认证过滤器 -->
- <beans:bean id="securityFilter"
- class="cn.com.abel.test.service.security.MySecurityFilter">
- <!-- 用户拥有的角色 -->
- <beans:property name="authenticationManager" ref="myAuthenticationManager" />
- <!-- 用户是否拥有所请求资源的权限 -->
- <beans:property name="accessDecisionManager" ref="myAccessDecisionManager" />
- <!-- 资源与角色的对应关系 -->
- <beans:property name="securityMetadataSource" ref="mySecurityMetadataSource" />
- <!-- <beans:property name="rejectPublicInvocations" value="true"/> -->
- </beans:bean>
- <beans:bean id="myAccessDecisionManager" class="myAccessDecisionManager"></beans:bean>
- <beans:bean id="mySecurityMetadataSource"
- class="cn.com.abel.test.service.security.MySecurityMetadataSource">
- <beans:constructor-arg>
- <beans:ref bean="resourceService" />
- </beans:constructor-arg>
- </beans:bean>
- <beans:bean id="encoder" class="org.springframework.security.authentication.encoding.Md5PasswordEncoder"></beans:bean>
- </beans:beans>
<?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.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security.xsd"><!-- entry-point-ref 配置自定义登录 -->
<http use-expressions="true" entry-point-ref="authenticationProcessingFilterEntryPoint"> <!-- 登出配置 -->
<logout logout-url="/j_spring_security_logout" logout-success-url="/login" /> <access-denied-handler error-page="/noPower" /> <!-- 过滤不被拦截的请求 -->
<intercept-url pattern="/login*" access="permitAll" />
<intercept-url pattern="/resources/**" access="permitAll" /> <!-- 只有权限才能访问的请求 -->
<intercept-url pattern="/admin/**" access="isAuthenticated()" /> <custom-filter ref="loginFilter" position="FORM_LOGIN_FILTER" />
<custom-filter ref="securityFilter" before="FILTER_SECURITY_INTERCEPTOR" /> </http> <beans:bean id="loginFilter"
class="cn.com.abel.test.service.security.MyUsernamePasswordAuthenticationFilter"> <!-- 登录提交处理 -->
<beans:property name="filterProcessesUrl" value="/j_spring_security_check"></beans:property> <!-- 登录成功跳转 -->
<beans:property name="authenticationSuccessHandler"
ref="loginLogAuthenticationSuccessHandler"></beans:property> <!-- 设置登录失败的网址 -->
<beans:property name="authenticationFailureHandler"
ref="simpleUrlAuthenticationFailureHandler"></beans:property> <!-- 用户拥有权限 -->
<beans:property name="authenticationManager" ref="myAuthenticationManager"></beans:property>
</beans:bean> <beans:bean id="loginLogAuthenticationSuccessHandler"
class="org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler">
<beans:property name="defaultTargetUrl" value="/admin/index"></beans:property>
</beans:bean>
<beans:bean id="simpleUrlAuthenticationFailureHandler"
class="org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler">
<beans:property name="defaultFailureUrl" value="/login"></beans:property>
</beans:bean> <authentication-manager alias="myAuthenticationManager">
<authentication-provider user-service-ref="myUserDetailServiceImpl">
<password-encoder ref="encoder" />
</authentication-provider>
</authentication-manager> <beans:bean id="myUserDetailServiceImpl"
class="cn.com.abel.test.service.security.AdminUserDetailServiceImpl">
</beans:bean> <beans:bean id="authenticationProcessingFilterEntryPoint"
class="org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint">
<beans:property name="loginFormUrl" value="/login"></beans:property>
</beans:bean> <!-- 认证过滤器 -->
<beans:bean id="securityFilter"
class="cn.com.abel.test.service.security.MySecurityFilter">
<!-- 用户拥有的角色 -->
<beans:property name="authenticationManager" ref="myAuthenticationManager" />
<!-- 用户是否拥有所请求资源的权限 -->
<beans:property name="accessDecisionManager" ref="myAccessDecisionManager" />
<!-- 资源与角色的对应关系 -->
<beans:property name="securityMetadataSource" ref="mySecurityMetadataSource" />
<!-- <beans:property name="rejectPublicInvocations" value="true"/> --> </beans:bean> <beans:bean id="myAccessDecisionManager" class="myAccessDecisionManager"></beans:bean> <beans:bean id="mySecurityMetadataSource"
class="cn.com.abel.test.service.security.MySecurityMetadataSource">
<beans:constructor-arg>
<beans:ref bean="resourceService" />
</beans:constructor-arg>
</beans:bean> <beans:bean id="encoder" class="org.springframework.security.authentication.encoding.Md5PasswordEncoder"></beans:bean>
</beans:beans>
3、MyUsernamePasswordAuthenticationFilter.java
- package cn.com.abel.test.service.security;
- import javax.servlet.http.HttpServletRequest;
- import javax.servlet.http.HttpServletResponse;
- import org.springframework.security.authentication.AuthenticationServiceException;
- import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
- import org.springframework.security.core.Authentication;
- import org.springframework.security.core.AuthenticationException;
- import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
- public class MyUsernamePasswordAuthenticationFilter extends UsernamePasswordAuthenticationFilter{
- @Override
- public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {
- if (!request.getMethod().equals("POST")) {
- throw new AuthenticationServiceException("Authentication method not supported: " + request.getMethod());
- }
- String username = obtainUsername(request);
- String password = obtainPassword(request);
- if (username == null) {
- username = "";
- }
- if (password == null) {
- password = "";
- }
- username = username.trim();
- UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(username, password);
- // Allow subclasses to set the "details" property
- setDetails(request, authRequest);
- // //登录验证码,如需要开启把下面注释去掉则可
- // String authCode = StringUtils.defaultString(request.getParameter("authCode"));
- // if(!AdwImageCaptchaServlet.validateResponse(request, authCode)){
- // throw new AuthenticationServiceException("validCode.auth.fail");
- // }
- return this.getAuthenticationManager().authenticate(authRequest);
- }
- }
package cn.com.abel.test.service.security; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import org.springframework.security.authentication.AuthenticationServiceException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; public class MyUsernamePasswordAuthenticationFilter extends UsernamePasswordAuthenticationFilter{@Override
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException { if (!request.getMethod().equals("POST")) {
throw new AuthenticationServiceException("Authentication method not supported: " + request.getMethod());
} String username = obtainUsername(request);
String password = obtainPassword(request); if (username == null) {
username = "";
} if (password == null) {
password = "";
} username = username.trim(); UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(username, password); // Allow subclasses to set the "details" property
setDetails(request, authRequest);
// //登录验证码,如需要开启把下面注释去掉则可
// String authCode = StringUtils.defaultString(request.getParameter("authCode"));
// if(!AdwImageCaptchaServlet.validateResponse(request, authCode)){
// throw new AuthenticationServiceException("validCode.auth.fail");
// }return this.getAuthenticationManager().authenticate(authRequest);
}
}
4、MySecurityFilter.java
- package cn.com.abel.test.service.security;
- import java.io.IOException;
- 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.SecurityMetadataSource;
- import org.springframework.security.access.intercept.AbstractSecurityInterceptor;
- import org.springframework.security.access.intercept.InterceptorStatusToken;
- import org.springframework.security.web.FilterInvocation;
- import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource;
- public class MySecurityFilter extends AbstractSecurityInterceptor implements Filter {
- //与applicationContext-security.xml里的myFilter的属性securityMetadataSource对应,
- //其他的两个组件,已经在AbstractSecurityInterceptor定义
- private FilterInvocationSecurityMetadataSource securityMetadataSource;
- @Override
- public SecurityMetadataSource obtainSecurityMetadataSource() {
- return this.securityMetadataSource;
- }
- public void doFilter(ServletRequest request, ServletResponse response,
- FilterChain chain) throws IOException, ServletException {
- FilterInvocation fi = new FilterInvocation(request, response, chain);
- invoke(fi);
- }
- private void invoke(FilterInvocation fi) throws IOException, ServletException {
- // object为FilterInvocation对象
- //1.获取请求资源的权限
- //执行Collection<ConfigAttribute> attributes = SecurityMetadataSource.getAttributes(object);
- //2.是否拥有权限
- //获取安全主体,可以强制转换为UserDetails的实例
- //1) UserDetails
- // Authentication authenticated = authenticateIfRequired();
- //this.accessDecisionManager.decide(authenticated, object, attributes);
- //用户拥有的权限
- //2) GrantedAuthority
- //Collection<GrantedAuthority> authenticated.getAuthorities()
- //System.out.println("用户发送请求! ");
- InterceptorStatusToken token = null;
- token = super.beforeInvocation(fi);
- try {
- fi.getChain().doFilter(fi.getRequest(), fi.getResponse());
- } finally {
- super.afterInvocation(token, null);
- }
- }
- public FilterInvocationSecurityMetadataSource getSecurityMetadataSource() {
- return securityMetadataSource;
- }
- public void setSecurityMetadataSource(FilterInvocationSecurityMetadataSource securityMetadataSource) {
- this.securityMetadataSource = securityMetadataSource;
- }
- public void init(FilterConfig arg0) throws ServletException {
- // TODO Auto-generated method stub
- }
- public void destroy() {
- // TODO Auto-generated method stub
- }
- @Override
- public Class<? extends Object> getSecureObjectClass() {
- //下面的MyAccessDecisionManager的supports方面必须放回true,否则会提醒类型错误
- return FilterInvocation.class;
- }
- }
package cn.com.abel.test.service.security; import java.io.IOException; 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.SecurityMetadataSource;
import org.springframework.security.access.intercept.AbstractSecurityInterceptor;
import org.springframework.security.access.intercept.InterceptorStatusToken;
import org.springframework.security.web.FilterInvocation;
import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource; public class MySecurityFilter extends AbstractSecurityInterceptor implements Filter {
//与applicationContext-security.xml里的myFilter的属性securityMetadataSource对应,
//其他的两个组件,已经在AbstractSecurityInterceptor定义
private FilterInvocationSecurityMetadataSource securityMetadataSource;@Override
public SecurityMetadataSource obtainSecurityMetadataSource() {
return this.securityMetadataSource;
} public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
FilterInvocation fi = new FilterInvocation(request, response, chain);
invoke(fi);
} private void invoke(FilterInvocation fi) throws IOException, ServletException {
// object为FilterInvocation对象
//1.获取请求资源的权限
//执行Collection<ConfigAttribute> attributes = SecurityMetadataSource.getAttributes(object);
//2.是否拥有权限
//获取安全主体,可以强制转换为UserDetails的实例
//1) UserDetails
// Authentication authenticated = authenticateIfRequired();
//this.accessDecisionManager.decide(authenticated, object, attributes);
//用户拥有的权限
//2) GrantedAuthority
//Collection<GrantedAuthority> authenticated.getAuthorities()
//System.out.println("用户发送请求! ");
InterceptorStatusToken token = null; token = super.beforeInvocation(fi); try {
fi.getChain().doFilter(fi.getRequest(), fi.getResponse());
} finally {
super.afterInvocation(token, null);
}
} public FilterInvocationSecurityMetadataSource getSecurityMetadataSource() {
return securityMetadataSource;
} public void setSecurityMetadataSource(FilterInvocationSecurityMetadataSource securityMetadataSource) {
this.securityMetadataSource = securityMetadataSource;
} public void init(FilterConfig arg0) throws ServletException {
// TODO Auto-generated method stub
} public void destroy() {
// TODO Auto-generated method stub } @Override
public Class<? extends Object> getSecureObjectClass() {
//下面的MyAccessDecisionManager的supports方面必须放回true,否则会提醒类型错误
return FilterInvocation.class;
}
}
5、AdminUserDetailServiceImpl.java
- package cn.com.abel.test.service.security;
- import java.util.HashSet;
- import java.util.List;
- import java.util.Set;
- 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 cn.com.abel.test.model.RoleModel;
- import cn.com.abel.test.model.MemberModel;
- import cn.com.abel.test.service.RoleService;
- import cn.com.abel.test.service.MemberService;
- public class AdminUserDetailServiceImpl implements UserDetailsService {
- @Autowired
- private MemberService memberService;
- @Autowired
- RoleService roleService;
- //登录验证
- public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
- MemberModel member = memberService.getUserDetailsByUserName(username);
- if(member==null){
- throw new UsernameNotFoundException("member "+username +" not found.");
- }
- Set<GrantedAuthority> grantedAuths = obtionGrantedAuthorities(member);
- //封装成spring security的user
- User userdetail = new User(user.getUserName(), user.getPassword(),
- true, // 账号状态 0 表示停用 1表示启用
- true, true, true, grantedAuths // 用户的权限
- );
- return userdetail;
- }
- //取得用户的权限
- private Set<GrantedAuthority> obtionGrantedAuthorities(MemberModel member) {
- Set<GrantedAuthority> authSet = new HashSet<GrantedAuthority>();
- List<RoleModel> roles = roleService.getRoleByUser(member)<span style="font-family:Arial, Helvetica, sans-serif;">;</span>
- if(roles!=null){
- for(RoleModel role : roles) {
- authSet.add(new SimpleGrantedAuthority(role.getRoleCode().trim()));
- }
- }
- return authSet;
- }
- }
package cn.com.abel.test.service.security; import java.util.HashSet;
import java.util.List;
import java.util.Set; 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 cn.com.abel.test.model.RoleModel;
import cn.com.abel.test.model.MemberModel;
import cn.com.abel.test.service.RoleService;
import cn.com.abel.test.service.MemberService; public class AdminUserDetailServiceImpl implements UserDetailsService {
@Autowired
private MemberService memberService;
@Autowired
RoleService roleService;//登录验证
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { MemberModel member = memberService.getUserDetailsByUserName(username); if(member==null){
throw new UsernameNotFoundException("member "+username +" not found.");
}
Set<GrantedAuthority> grantedAuths = obtionGrantedAuthorities(member); //封装成spring security的user
User userdetail = new User(user.getUserName(), user.getPassword(),
true, // 账号状态 0 表示停用 1表示启用
true, true, true, grantedAuths // 用户的权限
);
return userdetail;
} //取得用户的权限
private Set<GrantedAuthority> obtionGrantedAuthorities(MemberModel member) { Set<GrantedAuthority> authSet = new HashSet<GrantedAuthority>(); List<RoleModel> roles = roleService.getRoleByUser(member)<span style="font-family:Arial, Helvetica, sans-serif;">;</span>
if(roles!=null){
for(RoleModel role : roles) {
authSet.add(new SimpleGrantedAuthority(role.getRoleCode().trim()));
}
} return authSet;
}
}
6、MyAccessDecisionManager.java
- package cn.com.abel.test.service.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.authentication.InsufficientAuthenticationException;
- import org.springframework.security.core.Authentication;
- import org.springframework.security.core.GrantedAuthority;
- public class MyAccessDecisionManager implements AccessDecisionManager {
- public void decide(Authentication authentication, Object object, Collection<ConfigAttribute> configAttributes) throws AccessDeniedException, InsufficientAuthenticationException {
- if(configAttributes == null) {
- return;
- }
- //所请求的资源拥有的权限(一个资源对多个权限)
- Iterator<ConfigAttribute> iterator = configAttributes.iterator();
- while(iterator.hasNext()) {
- ConfigAttribute configAttribute = iterator.next();
- //访问所请求资源所需要的权限
- String needPermission = configAttribute.getAttribute();
- System.out.println("needPermission is " + needPermission);
- //用户所拥有的权限authentication
- for(GrantedAuthority ga : authentication.getAuthorities()) {
- if(needPermission.equals(ga.getAuthority())) {
- return;
- }
- }
- }
- //没有权限让我们去捕捉
- throw new AccessDeniedException(" 没有权限访问!");
- }
- public boolean supports(ConfigAttribute attribute) {
- // TODO Auto-generated method stub
- return true;
- }
- public boolean supports(Class<?> clazz) {
- // TODO Auto-generated method stub
- return true;
- }
- }
package cn.com.abel.test.service.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.authentication.InsufficientAuthenticationException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority; public class MyAccessDecisionManager implements AccessDecisionManager {public void decide(Authentication authentication, Object object, Collection<ConfigAttribute> configAttributes) throws AccessDeniedException, InsufficientAuthenticationException {
if(configAttributes == null) {
return;
}
//所请求的资源拥有的权限(一个资源对多个权限)
Iterator<ConfigAttribute> iterator = configAttributes.iterator();
while(iterator.hasNext()) {
ConfigAttribute configAttribute = iterator.next();
//访问所请求资源所需要的权限
String needPermission = configAttribute.getAttribute();
System.out.println("needPermission is " + needPermission);
//用户所拥有的权限authentication
for(GrantedAuthority ga : authentication.getAuthorities()) {
if(needPermission.equals(ga.getAuthority())) {
return;
}
}
}
//没有权限让我们去捕捉
throw new AccessDeniedException(" 没有权限访问!");
} public boolean supports(ConfigAttribute attribute) {
// TODO Auto-generated method stub
return true;
} public boolean supports(Class<?> clazz) {
// TODO Auto-generated method stub
return true;
}
}
7、MySecurityMetadataSource.java
- package cn.com.abel.test.service.security;
- import java.util.ArrayList;
- import java.util.Collection;
- import java.util.HashSet;
- import java.util.Iterator;
- import java.util.List;
- import java.util.Map;
- import java.util.Map.Entry;
- import java.util.TreeMap;
- import java.util.concurrent.ConcurrentHashMap;
- import javax.servlet.http.HttpServletRequest;
- import org.apache.commons.lang.StringUtils;
- import org.springframework.beans.factory.InitializingBean;
- 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.matcher.AntPathRequestMatcher;
- import org.springframework.security.web.util.matcher.RequestMatcher;
- import cn.com.abel.test.model.RoleModel;
- import cn.com.abel.test.service.ResourceService;
- public class MySecurityMetadataSource implements FilterInvocationSecurityMetadataSource,InitializingBean {
- private static final String AUTH_NO_ROLE =" __AUTH_NO_ROLE__";
- private ResourceService resourceService;
- public MySecurityMetadataSource(ResourceService resourceService) {
- this.resourceService = resourceService;
- }
- private static Map<String, Collection<ConfigAttribute>> resourceMap = null;
- public Collection<ConfigAttribute> getAllConfigAttributes() {
- return null;
- }
- public boolean supports(Class<?> clazz) {
- return true;
- }
- private void loadResourceDefine() {
- if(resourceMap == null) {
- resourceMap = new ConcurrentHashMap<String, Collection<ConfigAttribute>>();
- }else{
- resourceMap.clear();
- }
- Map<String,List<RoleModel>> resourceRoleMap = resourceService.getAllResourceRole();
- for (Entry<String,List<RoleModel>> entry : resourceRoleMap.entrySet()) {
- String url = entry.getKey();
- List<RoleModel> values = entry.getValue();
- Collection<ConfigAttribute> configAttributes = new ArrayList<ConfigAttribute>();
- for(RoleModel secRoleModel : values){
- ConfigAttribute configAttribute = new SecurityConfig(StringUtils.defaultString(secRoleModel.getRoleCode(),AUTH_NO_ROLE));
- configAttributes.add(configAttribute);
- }
- resourceMap.put(url, configAttributes);
- }
- }
- public Collection<ConfigAttribute> getAttributes(Object object) throws IllegalArgumentException {
- HttpServletRequest request = ((FilterInvocation) object).getHttpRequest();
- TreeMap<String, Collection<ConfigAttribute>> attrMap = new TreeMap<String, Collection<ConfigAttribute>>(resourceMap);
- Iterator<String> ite = attrMap.keySet().iterator();
- RequestMatcher urlMatcher = null;
- Collection<ConfigAttribute> attrSet = new HashSet<ConfigAttribute>();
- //match all of /admin/** a/b/**
- while (ite.hasNext()) {
- String resURL = ite.next();
- urlMatcher = new AntPathRequestMatcher(resURL);
- if (urlMatcher.matches(request)||StringUtils.equals(request.getRequestURI(),resURL)) {
- attrSet.addAll(attrMap.get(resURL));
- }
- }
- if(!attrSet.isEmpty()){
- return attrSet;
- }
- return null;
- }
- @Override
- public void afterPropertiesSet() throws Exception {
- loadResourceDefine() ;
- }
- }
package cn.com.abel.test.service.security; import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.TreeMap;
import java.util.concurrent.ConcurrentHashMap; import javax.servlet.http.HttpServletRequest; import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.InitializingBean;
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.matcher.AntPathRequestMatcher;
import org.springframework.security.web.util.matcher.RequestMatcher; import cn.com.abel.test.model.RoleModel;
import cn.com.abel.test.service.ResourceService; public class MySecurityMetadataSource implements FilterInvocationSecurityMetadataSource,InitializingBean {private static final String AUTH_NO_ROLE =" __AUTH_NO_ROLE__"; private ResourceService resourceService; public MySecurityMetadataSource(ResourceService resourceService) {
this.resourceService = resourceService;
} private static Map<String, Collection<ConfigAttribute>> resourceMap = null; public Collection<ConfigAttribute> getAllConfigAttributes() {
return null;
} public boolean supports(Class<?> clazz) {
return true;
}
private void loadResourceDefine() {
if(resourceMap == null) {
resourceMap = new ConcurrentHashMap<String, Collection<ConfigAttribute>>();
}else{
resourceMap.clear();
} Map<String,List<RoleModel>> resourceRoleMap = resourceService.getAllResourceRole(); for (Entry<String,List<RoleModel>> entry : resourceRoleMap.entrySet()) {
String url = entry.getKey();
List<RoleModel> values = entry.getValue(); Collection<ConfigAttribute> configAttributes = new ArrayList<ConfigAttribute>();
for(RoleModel secRoleModel : values){
ConfigAttribute configAttribute = new SecurityConfig(StringUtils.defaultString(secRoleModel.getRoleCode(),AUTH_NO_ROLE));
configAttributes.add(configAttribute);
}
resourceMap.put(url, configAttributes);
}
}
public Collection<ConfigAttribute> getAttributes(Object object) throws IllegalArgumentException { HttpServletRequest request = ((FilterInvocation) object).getHttpRequest(); TreeMap<String, Collection<ConfigAttribute>> attrMap = new TreeMap<String, Collection<ConfigAttribute>>(resourceMap); Iterator<String> ite = attrMap.keySet().iterator(); RequestMatcher urlMatcher = null; Collection<ConfigAttribute> attrSet = new HashSet<ConfigAttribute>();
//match all of /admin/** a/b/**
while (ite.hasNext()) { String resURL = ite.next();
urlMatcher = new AntPathRequestMatcher(resURL); if (urlMatcher.matches(request)||StringUtils.equals(request.getRequestURI(),resURL)) {
attrSet.addAll(attrMap.get(resURL));
}
} if(!attrSet.isEmpty()){
return attrSet;
}
return null;
} @Override
public void afterPropertiesSet() throws Exception {
loadResourceDefine() ;
}
}
8、ResourceService.java
此类是为从数据库获取系统中的资源所属的角色,根据自己的数据表自行编写。
- package cn.com.abel.test.service;
- import java.util.ArrayList;
- import java.util.HashMap;
- import java.util.HashSet;
- import java.util.List;
- import java.util.Map;
- import org.apache.commons.collections.CollectionUtils;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.stereotype.Service;
- import cn.com.abel.test.mapper.ResourceModelMapper;
- import cn.com.abel.test.mapper.RoleModelMapper;
- import cn.com.abel.test.mapper.RoleResourcetModelMapper;
- import cn.com.abel.test.model.ResourceModel;
- import cn.com.abel.test.model.ResourceModelCriteria;
- import cn.com.abel.test.model.RoleModel;
- import cn.com.abel.test.model.RoleModelCriteria;
- import cn.com.abel.test.model.RoleResourcetModel;
- import cn.com.abel.test.model.RoleResourcetModelCriteria;
- @Service
- public class ResourceService {
- @Autowired
- ResourceModelMapper resourceModelMapper;
- @Autowired
- RoleModelMapper roleMapper;
- @Autowired
- RoleResourcetModelMapper roleResMapper;
- /**
- * 获取各个资源(url)对应的角色
- * @return
- */
- public Map<String,List<RoleModel>> getAllResourceRole(){
- Map<String,List<RoleModel>> resultMap = new HashMap<String,List<RoleModel>>();
- ResourceModelCriteria secResourceModelExample = new ResourceModelCriteria();
- List<ResourceModel> resourceList = resourceModelMapper.selectByExample(secResourceModelExample);
- if(CollectionUtils.isNotEmpty(resourceList)){
- for(ResourceModel secResourceModel : resourceList){
- RoleModelCriteria roleCriteria = new RoleModelCriteria();
- roleCriteria.createCriteria().andIdIn(getRoleIdsByResourceId(secResourceModel.getId()));
- List<RoleModel> roleList = roleMapper.selectByExample(roleCriteria);
- resultMap.put(secResourceModel.getValue(), roleList);
- }
- }
- return resultMap;
- }
- public List<Integer> getRoleIdsByResourceId(Integer resourceId){
- List<Integer> roleIds = new ArrayList<Integer>();
- RoleResourcetModelCriteria criteria = new RoleResourcetModelCriteria();
- criteria.createCriteria().andResourceIdEqualTo(resourceId);
- List<RoleResourcetModel> list = roleResMapper.selectByExample(criteria);
- if(CollectionUtils.isNotEmpty(list)){
- for(RoleResourcetModel model : list){
- roleIds.add(model.getRoleId());
- }
- }
- HashSet<Integer> h = new HashSet<Integer>(roleIds);
- roleIds.clear();
- roleIds.addAll(h);
- return roleIds;
- }
- }
package cn.com.abel.test.service; import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map; import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import cn.com.abel.test.mapper.ResourceModelMapper;
import cn.com.abel.test.mapper.RoleModelMapper;
import cn.com.abel.test.mapper.RoleResourcetModelMapper;
import cn.com.abel.test.model.ResourceModel;
import cn.com.abel.test.model.ResourceModelCriteria;
import cn.com.abel.test.model.RoleModel;
import cn.com.abel.test.model.RoleModelCriteria;
import cn.com.abel.test.model.RoleResourcetModel;
import cn.com.abel.test.model.RoleResourcetModelCriteria; @Service
public class ResourceService {@Autowired
ResourceModelMapper resourceModelMapper; @Autowired
RoleModelMapper roleMapper; @Autowired
RoleResourcetModelMapper roleResMapper; /**
* 获取各个资源(url)对应的角色
* @return
*/
public Map<String,List<RoleModel>> getAllResourceRole(){ Map<String,List<RoleModel>> resultMap = new HashMap<String,List<RoleModel>>(); ResourceModelCriteria secResourceModelExample = new ResourceModelCriteria();
List<ResourceModel> resourceList = resourceModelMapper.selectByExample(secResourceModelExample); if(CollectionUtils.isNotEmpty(resourceList)){
for(ResourceModel secResourceModel : resourceList){
RoleModelCriteria roleCriteria = new RoleModelCriteria();
roleCriteria.createCriteria().andIdIn(getRoleIdsByResourceId(secResourceModel.getId()));
List<RoleModel> roleList = roleMapper.selectByExample(roleCriteria);
resultMap.put(secResourceModel.getValue(), roleList); }
} return resultMap;
} public List<Integer> getRoleIdsByResourceId(Integer resourceId){
List<Integer> roleIds = new ArrayList<Integer>(); RoleResourcetModelCriteria criteria = new RoleResourcetModelCriteria();
criteria.createCriteria().andResourceIdEqualTo(resourceId);
List<RoleResourcetModel> list = roleResMapper.selectByExample(criteria);
if(CollectionUtils.isNotEmpty(list)){
for(RoleResourcetModel model : list){
roleIds.add(model.getRoleId());
}
} HashSet<Integer> h = new HashSet<Integer>(roleIds);
roleIds.clear();
roleIds.addAll(h);
return roleIds;
}
}
最后附上数据表的SQL:
- CREATE TABLE `auth_resource` (
- `id` INT(11) NOT NULL AUTO_INCREMENT,
- `name` VARCHAR(100) NULL DEFAULT NULL COMMENT '资源名称',
- `value` VARCHAR(100) NULL DEFAULT NULL COMMENT '资源值',
- `summary` VARCHAR(1000) NULL DEFAULT NULL COMMENT '资源描述',
- `updated_time` DATETIME NULL DEFAULT NULL,
- `updated_user` VARCHAR(100) NULL DEFAULT NULL,
- PRIMARY KEY (`id`)
- )
- COMMENT='资源访问表'
- COLLATE='utf8_general_ci'
- ENGINE=InnoDB;
- CREATE TABLE `auth_role` (
- `id` INT(11) NOT NULL AUTO_INCREMENT,
- `role_name` VARCHAR(100) NULL DEFAULT NULL COMMENT '角色名称',
- `role_code` VARCHAR(100) NULL DEFAULT NULL COMMENT '角色代码',
- `updated_time` DATETIME NULL DEFAULT NULL,
- `updated_user` VARCHAR(100) NULL DEFAULT NULL,
- PRIMARY KEY (`id`)
- )
- COMMENT='角色表'
- COLLATE='utf8_general_ci'
- ENGINE=InnoDB;
- CREATE TABLE `role_resource` (
- `id` INT(11) NOT NULL AUTO_INCREMENT,
- `role_id` INT(11) NOT NULL,
- `resource_id` INT(11) NOT NULL,
- PRIMARY KEY (`id`),
- UNIQUE INDEX `role_id_resource_id` (`role_id`, `resource_id`)
- )
- COMMENT='资源角色关联表'
- COLLATE='utf8_general_ci'
- ENGINE=InnoDB;
- CREATE TABLE `member` (
- `id` INT(11) NOT NULL AUTO_INCREMENT,
- `user_name` VARCHAR(100) NULL DEFAULT NULL,
- `nick` VARCHAR(100) NULL DEFAULT NULL,
- `password` VARCHAR(100) NULL DEFAULT NULL,
- `sex` INT(11) NULL DEFAULT NULL,
- `birthday` DATE NULL DEFAULT NULL,
- `mobile` VARCHAR(50) NULL DEFAULT NULL,
- `email` VARCHAR(50) NULL DEFAULT NULL,
- `address` VARCHAR(512) NULL DEFAULT NULL,
- `regip` VARCHAR(100) NULL DEFAULT NULL,
- `created_time` DATETIME NULL DEFAULT NULL,
- PRIMARY KEY (`id`)
- )
- COMMENT='用户表'
- COLLATE='utf8_general_ci'
- ENGINE=InnoDB
- AUTO_INCREMENT=2;
- CREATE TABLE `member_role` (
- `id` INT(11) NOT NULL AUTO_INCREMENT,
- `member_id` INT(11) NOT NULL,
- `role_id` INT(11) NOT NULL,
- PRIMARY KEY (`id`),
- UNIQUE INDEX `member_id_role_id` (`member_id`, `role_id`)
- )
- COMMENT='用户角色关联表'
- COLLATE='utf8_general_ci'
- ENGINE=InnoDB;
CREATE TABLE `auth_resource` (
`id` INT(11) NOT NULL AUTO_INCREMENT,
`name` VARCHAR(100) NULL DEFAULT NULL COMMENT '资源名称',
`value` VARCHAR(100) NULL DEFAULT NULL COMMENT '资源值',
`summary` VARCHAR(1000) NULL DEFAULT NULL COMMENT '资源描述',
`updated_time` DATETIME NULL DEFAULT NULL,
`updated_user` VARCHAR(100) NULL DEFAULT NULL,
PRIMARY KEY (`id`)
)
COMMENT='资源访问表'
COLLATE='utf8_general_ci'
ENGINE=InnoDB; CREATE TABLEauth_role(
idINT(11) NOT NULL AUTO_INCREMENT,
role_nameVARCHAR(100) NULL DEFAULT NULL COMMENT '角色名称',
role_codeVARCHAR(100) NULL DEFAULT NULL COMMENT '角色代码',
updated_timeDATETIME NULL DEFAULT NULL,
updated_userVARCHAR(100) NULL DEFAULT NULL,
PRIMARY KEY (id)
)
COMMENT='角色表'
COLLATE='utf8_general_ci'
ENGINE=InnoDB; CREATE TABLErole_resource(
idINT(11) NOT NULL AUTO_INCREMENT,
role_idINT(11) NOT NULL,
resource_idINT(11) NOT NULL,
PRIMARY KEY (id),
UNIQUE INDEXrole_id_resource_id(role_id,resource_id)
)
COMMENT='资源角色关联表'
COLLATE='utf8_general_ci'
ENGINE=InnoDB; CREATE TABLEmember(
idINT(11) NOT NULL AUTO_INCREMENT,
user_nameVARCHAR(100) NULL DEFAULT NULL,
nickVARCHAR(100) NULL DEFAULT NULL,
passwordVARCHAR(100) NULL DEFAULT NULL,
sexINT(11) NULL DEFAULT NULL,
birthdayDATE NULL DEFAULT NULL,
mobileVARCHAR(50) NULL DEFAULT NULL,
addressVARCHAR(512) NULL DEFAULT NULL,
regipVARCHAR(100) NULL DEFAULT NULL,
created_timeDATETIME NULL DEFAULT NULL,
PRIMARY KEY (id)
)
COMMENT='用户表'
COLLATE='utf8_general_ci'
ENGINE=InnoDB
AUTO_INCREMENT=2; CREATE TABLEmember_role(
idINT(11) NOT NULL AUTO_INCREMENT,
member_idINT(11) NOT NULL,
role_idINT(11) NOT NULL,
PRIMARY KEY (id),
UNIQUE INDEXmember_id_role_id(member_id,role_id)
)
COMMENT='用户角色关联表'
COLLATE='utf8_general_ci'
ENGINE=InnoDB;
完整代码下载(包含数据库):http://download.csdn.net/download/rongku/9931455
spring security 登录、权限管理配置的更多相关文章
- 使用Spring Security实现权限管理
使用Spring Security实现权限管理 1.技术目标 了解并创建Security框架所需数据表 为项目添加Spring Security框架 掌握Security框架配置 应用Security ...
- Spring Security 之Session管理配置
废话不多说,直接上代码.示例如下: 1. 新建Maven项目 session 2. pom.xml <project xmlns="http://maven.apache.o ...
- springBoot整合spring security实现权限管理(单体应用版)--筑基初期
写在前面 在前面的学习当中,我们对spring security有了一个小小的认识,接下来我们整合目前的主流框架springBoot,实现权限的管理. 在这之前,假定你已经了解了基于资源的权限管理模型 ...
- (39.1) Spring Boot Shiro权限管理【从零开始学Spring Boot】
(本节提供源代码,在最下面可以下载)距上一个章节过了二个星期了,最近时间也是比较紧,一直没有时间可以写博客,今天难得有点时间,就说说Spring Boot如何集成Shiro吧.这个章节会比较复杂,牵涉 ...
- Spring Boot Shiro 权限管理
Spring Boot Shiro 权限管理 标签: springshiro 2016-01-14 23:44 94587人阅读 评论(60) 收藏 举报 .embody{ padding:10px ...
- spring boot rest 接口集成 spring security(1) - 最简配置
Spring Boot 集成教程 Spring Boot 介绍 Spring Boot 开发环境搭建(Eclipse) Spring Boot Hello World (restful接口)例子 sp ...
- SpringBoot 优雅配置跨域多种方式及Spring Security跨域访问配置的坑
前言 最近在做项目的时候,基于前后端分离的权限管理系统,后台使用 Spring Security 作为权限控制管理, 然后在前端接口访问时候涉及到跨域,但我怎么配置跨域也没有生效,这里有一个坑,在使用 ...
- Spring Security控制权限
Spring Security控制权限 1,配置过滤器 为了在项目中使用Spring Security控制权限,首先要在web.xml中配置过滤器,这样我们就可以控制对这个项目的每个请求了. < ...
- Spring Boot中使用 Spring Security 构建权限系统
Spring Security是一个能够为基于Spring的企业应用系统提供声明式的安全访问控制解决方案的安全框架.它提供了一组可以在Spring应用上下文中配置的Bean,为应用系统提供声明式的安全 ...
- Spring Security 登录校验 源码解析
传统情况下,在过滤器中做权限验证,Spring Secuirty也是在Filter中进行权限验证. 创建并注册过滤器 package com.awizdata.edubank.config; impo ...
随机推荐
- 如何启动Intel VT-x
如何启动Intel VT-x 5 在64bit win7系统下安装了Vmware10,然后安装64位的UbuntuKylin 14.04,想要打开UbuntuKylin,弹出如下对话框: 请问该如何启 ...
- 理想路径——双向BFS
题目 给n个点m条边(2 ≤ n ≤ 100000,1 ≤ m ≤ 200000)的无向图,每条边上都涂有一种颜色.求从结点1到结点n的一条路径,使得经过的边数尽量的少,在此前提下,经过边的颜色序列的 ...
- 由DAG到背包问题——记忆化搜索和递推两种解法
一.问题描述 物品无限的背包问题:有n种物品,每种均有无穷多个.第 i 种物品的体积为Vi,重量为Wi.选一些物品装到一个容量为 C 的背包中,求使得背包内物品总体积不超过C的前提下重量的最大值.1≤ ...
- 剑指offer44 扑克牌顺序
注意一个边界条件:必须是连续的,如果前后两个数是一样的也不满足条件 class Solution { public: bool IsContinuous( vector<int> numb ...
- ios 自定义RadioButton
1 前言 众所周知在IOS中没有单选按钮这一控件,今天我们来学习一下简单的单选控件.类似与Web中的radio表单元素. 2 详述 本控件单纯的利用按钮控件和NSObject的respondsToSe ...
- vs code背景图片的设置
使用vs code编辑器的时候,每次看到黑色的背景,会感觉到很大的视觉疲劳,今天来换换背景来看下效果 你需要安装的插件是background 然后在文件 => 首选项 => 设置搜索bac ...
- ssh 免密码登录 与 密钥公钥原理讲解
前言 由于最近频繁需要登录几个服务器,每次登录都需要输入密码,故相对麻烦. 由于个人服务器用于实验,故对安全性要求不是很高,故想实现ssh免密登录. 通过阅读ssh 公钥私钥认证操作及原理以及ssh公 ...
- Linux基础学习-chrony时间同步服务
Chrony时间同步 NTP(Network Time Protocol,网络时间协议)是用来使网络中的各个计算机时间同步的一种协议.它的用于是把计算机的时钟同步到世界协调时UTC,其精度在局域网内可 ...
- docker build no such file or directory
在我构建新的镜像的时候, 发生 了 no such file or directory 的错误. 这个错误找了半天, 没头绪, 后来灵光一现, 原来是我的文件夹名字写错了 我的目录结构是这样的 [ ...
- PyCharm 社区版创建Django项目的一个方法
PyCharm 社区版创建项目无法选择Django等项目,只能选择Python项目. 你在进行练习的时候为了方便,可以用过期了的PyCharm专业版在可用的30分钟内创建社区版本不支持的项目,再用Py ...