没事就来了解下spring security.网上找了很多资料。有过时的,也有不是很全面的。各种问题也算是让我碰了个遍。这样吧。我先把整个流程写下来,之后在各个易混点分析吧。

1.建立几个必要的页面。

login.jsp   index.jsp    user.jsp     admin.jsp    error.jsp 后面几个只是用来做跳转的,里面没什么要注意的,就贴出login里面的吧

  1. <html>
  2. <head>
  3. <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  4. <title>login</title>
  5. </head>
  6. <body>
  7. <form action="/mavenTest/j_spring_security_check" method="post">
  8. 账户:<input type="text" name="j_username" id="username"/>
  9. 密码:<input type="text" name="j_password" id="password"/>
  10. <input type="submit" value="登陆"/>
  11. </form>
  12. </body>
  13. </html>

2.配置web.xml  没有用的就没有粘贴了

  1. <filter>
  2. <filter-name>springSecurityFilterChain</filter-name>
  3. <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
  4. </filter>
  5.  
  6. <filter-mapping>
  7. <filter-name>springSecurityFilterChain</filter-name>
  8. <url-pattern>/*</url-pattern>
  9. </filter-mapping>

3.忘记吧pom.xml文件给出来了  版本为<org.springframework-version>3.2.3.RELEASE</org.springframework-version>

  1. <!-- spring security -->
  2. <dependency>
  3. <groupId>org.springframework.security</groupId>
  4. <artifactId>spring-security-core</artifactId>
  5. <version>${org.springframework-version}</version>
  6. </dependency>
  7.  
  8. <dependency>
  9. <groupId>org.springframework.security</groupId>
  10. <artifactId>spring-security-web</artifactId>
  11. <version>${org.springframework-version}</version>
  12. </dependency>
  13.  
  14. <dependency>
  15. <groupId>org.springframework.security</groupId>
  16. <artifactId>spring-security-config</artifactId>
  17. <version>${org.springframework-version}</version>
  18. </dependency>

4.配置spring security .xml文件

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans:beans xmlns="http://www.springframework.org/schema/security"
  3. xmlns:beans="http://www.springframework.org/schema/beans"
  4. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  5. xsi:schemaLocation="http://www.springframework.org/schema/beans
  6. http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
  7. http://www.springframework.org/schema/security
  8. http://www.springframework.org/schema/security/spring-security.xsd">
  9.  
  10. <!-- 不需要进行安全认证的资源 -->
  11. <http pattern="/resources/**" security="none" />
  12. <http pattern="/login.jsp" security="none"/>
  13.  
  14. <!-- 资源所需要的权限 -->
  15. <http auto-config='true'>
  16. <form-login login-page="/login.jsp"
  17. default-target-url="/index.jsp"
  18. authentication-failure-url="/login.jsp?error=true" />
  19. <logout logout-success-url="/index.jsp"/>
  20.  
  21. <!-- 尝试访问没有权限的页面时跳转的页面 -->
  22. <access-denied-handler error-page="/error-noauth.jsp"/>
  23.  
  24. <custom-filter ref="myFilter" before="FILTER_SECURITY_INTERCEPTOR"/>
  25. </http>
  26.  
  27. <!-- 自定义一个filter,必须包含authenticationManager,accessDecisionManager,
  28. securityMetadataSource三个属性 所有的功能都在这三个类中实现-->
  29.  
  30. <beans:bean id="myFilter" class="com.demo.im.model.security.MyFilterSecurotyInterceptor">
  31. <beans:property name="authenticationManager"
  32. ref="authenticationManager" />
  33. <beans:property name="accessDecisionManager"
  34. ref ="myAccessDecisionManagerBean"/>
  35. <beans:property name="securityMetadataSource"
  36. ref="securityMetadaSource"/>
  37. </beans:bean>
  38.  
  39. <!-- 认证管理器,实现用户认证的入口,主要实现userdetailsservice -->
  40. <authentication-manager alias="authenticationManager">
  41. <authentication-provider
  42. user-service-ref="myUserDetailService">
  43. </authentication-provider>
  44. </authentication-manager>
  45.  
  46. <beans:bean id="myUserDetailService"
  47. class="com.demo.im.model.security.DefaultUserDetailsService">
  48. </beans:bean>
  49.  
  50. <!-- 访问决策,决定某个用户具有的角色,是否有足够的权限去访问某个资源 -->
  51. <beans:bean id="myAccessDecisionManagerBean"
  52. class="com.demo.im.model.security.MyAccessDecisionManager" />
  53.  
  54. <beans:bean id="securityMetadaSource"
  55. class="com.demo.im.model.security.MyInvocationSecurityMetadaSource"/>
  56.  
  57. </beans:beans>

5.MyFilterSecurotyInterceptor   自定义filter的代码如下。

其中最核心的代码是  invoke() 方法中的

  1. InterceptorStatusToken token = super.beforeInvocation(fi);
    这一句在dofilter之前进行权限验证,而具体的实现交给了accessDecisionManager,下面将继续讨论
  1. package com.demo.im.model.security;
  2.  
  3. import java.io.IOException;
  4.  
  5. import javax.servlet.Filter;
  6. import javax.servlet.FilterChain;
  7. import javax.servlet.FilterConfig;
  8. import javax.servlet.ServletException;
  9. import javax.servlet.ServletRequest;
  10. import javax.servlet.ServletResponse;
  11.  
  12. import org.springframework.security.access.SecurityMetadataSource;
  13. import org.springframework.security.access.intercept.AbstractSecurityInterceptor;
  14. import org.springframework.security.access.intercept.InterceptorStatusToken;
  15. import org.springframework.security.web.FilterInvocation;
  16. import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource;
  17.  
  18. public class MyFilterSecurotyInterceptor extends AbstractSecurityInterceptor implements Filter {
  19.  
  20. private FilterInvocationSecurityMetadataSource securityMetadataSource;
  21.  
  22. @Override
  23. public void init(FilterConfig filterConfig) throws ServletException {
  24. // TODO Auto-generated method stub
  25.  
  26. }
  27.  
  28. @Override
  29. public void doFilter(ServletRequest request, ServletResponse response,
  30. FilterChain chain) throws IOException, ServletException {
  31.  
  32. FilterInvocation fi = new FilterInvocation(request, response,chain);
  33. invoke(fi);
  34. }
  35.  
  36. @Override
  37. public void destroy() {
  38. // TODO Auto-generated method stub
  39.  
  40. }
  41.  
  42. @Override
  43. public Class<?> getSecureObjectClass() {
  44. // TODO Auto-generated method stub
  45. return FilterInvocation.class;
  46. }
  47.  
  48. @Override
  49. public SecurityMetadataSource obtainSecurityMetadataSource() {
  50. // TODO Auto-generated method stub
  51. return this.securityMetadataSource;
  52. }
  53.  
  54. public FilterInvocationSecurityMetadataSource getSecurityMetadataSource() {
  55. return securityMetadataSource;
  56. }
  57.  
  58. public void setSecurityMetadataSource(FilterInvocationSecurityMetadataSource securityMetadataSource) {
  59. this.securityMetadataSource = securityMetadataSource;
  60. }
  61.  
  62. public void invoke(FilterInvocation fi) throws IOException
  63. ,ServletException{
  64.  
  65. InterceptorStatusToken token = super.beforeInvocation(fi);
  66. try {
  67. fi.getChain().doFilter(fi.getRequest(), fi.getResponse());
  68. } catch (Exception e) {
  69. // TODO: handle exception
  70. }finally{
  71. super.afterInvocation(token, null);
  72. }
  73. }
  74. }

6.DefaultUserDetailsService的实现

在这个类中你可以通过读取数据库来进行权限赋值,下面的代码未注解的是我写的静态的

  1. package com.demo.im.model.security;
  2.  
  3. import java.util.ArrayList;
  4. import java.util.Collection;
  5. import java.util.List;
  6.  
  7. import org.springframework.beans.factory.annotation.Autowired;
  8. import org.springframework.security.core.GrantedAuthority;
  9. import org.springframework.security.core.authority.GrantedAuthorityImpl;
  10. import org.springframework.security.core.userdetails.User;
  11. import org.springframework.security.core.userdetails.UserDetails;
  12. import org.springframework.security.core.userdetails.UserDetailsService;
  13. import org.springframework.security.core.userdetails.UsernameNotFoundException;
  14. import org.springframework.stereotype.Service;
  15.  
  16. import com.demo.im.entity.Role;
  17. import com.demo.im.entity.TUser;
  18. import com.demo.im.model.dao.TUserMapper;
  19. @Service
  20. public class DefaultUserDetailsService implements UserDetailsService {
  21. @Autowired
  22. TUserMapper userDao;
  23.  
  24. @Override
  25. public UserDetails loadUserByUsername(String username)
  26. throws UsernameNotFoundException {
  27. // TODO Auto-generated method stub
  28. System.out.println("userDetail********");
  29. Collection <GrantedAuthority> auths = new ArrayList<GrantedAuthority>();
  30.  
  31. GrantedAuthority auth2 = new GrantedAuthorityImpl("ROLE_ADMIN");
  32.  
  33. auths.add(auth2);
  34.  
  35. User user = new User(username,"1111",true,true,true,true,auths);
  36. return user;
  37.  
  38. // TUser paramU = new TUser();
  39. // paramU.setUsername(username);
  40. // List<TUser> userList = userDao.selectByUserParam(paramU);
  41. // TUser user = new TUser();
  42. // if(userList==null || userList.size()<=0){
  43. // throw new UsernameNotFoundException("username");
  44. // }
  45. // //得到用户权限
  46. // if(user.getRoles()!=null && user.getRoles().size()>0){
  47. //
  48. // for(Role role : user.getRoles()){
  49. // GrantedAuthority grantedAuthority = new GrantedAuthorityImpl(
  50. // role.getRolecode().toUpperCase());
  51. // auths.add(grantedAuthority);
  52. // }
  53. //
  54. // }
  55. // user.setAuthorities(auths);
  56. // return user;
  57. }
  58.  
  59. }

7.MyInvocationSecurityMetadaSource类的内容

这个类说白了就是从数据库中取出资源对应的权限,我这里也是写的静态的,修改为动态的方法也很简单,执行一个查询就行了

  1. package com.demo.im.model.security;
  2.  
  3. import java.util.ArrayList;
  4. import java.util.Collection;
  5. import java.util.HashMap;
  6. import java.util.Iterator;
  7. import java.util.Map;
  8.  
  9. import org.springframework.security.access.ConfigAttribute;
  10. import org.springframework.security.access.SecurityConfig;
  11. import org.springframework.security.web.FilterInvocation;
  12. import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource;
  13.  
  14. public class MyInvocationSecurityMetadaSource
  15. implements FilterInvocationSecurityMetadataSource{
  16.  
  17. // private UrlMatcher urlMatcher = new AntUrlPathMatcher();
  18. private static Map<String,Collection<ConfigAttribute>> resourceMap = null;
  19.  
  20. public MyInvocationSecurityMetadaSource(){
  21. loadResourceDefine();
  22. }
  23.  
  24. private void loadResourceDefine(){
  25. resourceMap = new HashMap<String, Collection<ConfigAttribute>>();
  26. Collection<ConfigAttribute> atts = new ArrayList<ConfigAttribute>();
  27.  
  28. ConfigAttribute ca = new SecurityConfig("ROLE_ADMIN");
  29.  
  30. atts.add(ca);
  31. resourceMap.put("/user.jsp", atts);
  32. resourceMap.put("/admin.jsp", atts);
  33. resourceMap.put("/index.jsp",atts);
  34.  
  35. }
  36.  
  37. @Override
  38. public Collection<ConfigAttribute> getAttributes(Object object)
  39. throws IllegalArgumentException {
  40. // TODO Auto-generated method stub
  41. String url = ((FilterInvocation)object).getRequestUrl();
  42. Iterator<String> ite = resourceMap.keySet().iterator();
  43.  
  44. while(ite.hasNext()){
  45. String resURL = ite.next();
  46.  
  47. if(url.equalsIgnoreCase(resURL)){
  48. return resourceMap.get(resURL);
  49. }
  50.  
  51. }
  52.  
  53. return null;
  54. }
  55.  
  56. @Override
  57. public Collection<ConfigAttribute> getAllConfigAttributes() {
  58. // TODO Auto-generated method stub
  59. return null;
  60. }
  61.  
  62. @Override
  63. public boolean supports(Class<?> clazz) {
  64. // TODO Auto-generated method stub
  65. return true;
  66. }
  67.  
  68. }

8.最后就是决策类了MyAccessDecisionManager

这个类就更好理解了,我们知道了用户的角色,我们也知道资源的角色,对比一下,也就是decide()一致就返回,不行就抛异常

  1. package com.demo.im.model.security;
  2.  
  3. import java.util.Collection;
  4. import java.util.Iterator;
  5.  
  6. import org.springframework.security.access.AccessDecisionManager;
  7. import org.springframework.security.access.AccessDeniedException;
  8. import org.springframework.security.access.ConfigAttribute;
  9. import org.springframework.security.access.SecurityConfig;
  10. import org.springframework.security.authentication.InsufficientAuthenticationException;
  11. import org.springframework.security.core.Authentication;
  12. import org.springframework.security.core.GrantedAuthority;
  13.  
  14. public class MyAccessDecisionManager implements AccessDecisionManager{
  15.  
  16. @Override
  17. public void decide(Authentication authentication, Object object,
  18. Collection<ConfigAttribute> configAttributes) throws AccessDeniedException,
  19. InsufficientAuthenticationException {
  20. if(configAttributes == null){
  21. return ;
  22. }
  23. System.out.println(object.toString());
  24. Iterator<ConfigAttribute> ite = configAttributes.iterator();
  25. while(ite.hasNext()){
  26. ConfigAttribute ca = ite.next();
  27. String needRole = ((SecurityConfig)ca).getAttribute();
  28.  
  29. for(GrantedAuthority ga : authentication.getAuthorities()){
  30. if(needRole.equals(ga.getAuthority())){
  31. return ;
  32. }
  33. }
  34. }
  35. throw new AccessDeniedException("no right");
  36.  
  37. }
  38.  
  39. @Override
  40. public boolean supports(ConfigAttribute arg0) {
  41. // TODO Auto-generated method stub
  42. return true;
  43. }
  44.  
  45. @Override
  46. public boolean supports(Class<?> arg0) {
  47. // TODO Auto-generated method stub
  48. return true;
  49. }
  50.  
  51. }

9总结:

到这里一个基本的spring  security算是搭建完了。过会在来说说我遇到的坑。方便以后大家找自己的坑。

spring security 3.2 配置详解(结合数据库)的更多相关文章

  1. Spring 入门 web.xml配置详解

    Spring 入门 web.xml配置详解 https://www.cnblogs.com/cczz_11/p/4363314.html https://blog.csdn.net/hellolove ...

  2. Spring学习 6- Spring MVC (Spring MVC原理及配置详解)

    百度的面试官问:Web容器,Servlet容器,SpringMVC容器的区别: 我还写了个文章,说明web容器与servlet容器的联系,参考:servlet单实例多线程模式 这个文章有web容器与s ...

  3. Spring Security之Remember me详解

    Remember me功能就是勾选"记住我"后,一次登录,后面在有效期内免登录. 先看具体配置: pom文件: <dependency> <groupId> ...

  4. spring boot application properties配置详解

    # =================================================================== # COMMON SPRING BOOT PROPERTIE ...

  5. 笔记:Spring Cloud Ribbon 客户端配置详解

    自动化配置 由于 Ribbon 中定义的每一个接口都有多种不同的策略实现,同时这些接口之间又有一定的依赖关系,Spring Cloud Ribbon 中的自动化配置能够很方便的自动化构建接口的具体实现 ...

  6. 电商网站开发记录(三) Spring的引入,以及配置详解

    1.web.xml配置注解<?xml version="1.0" encoding="UTF-8"?><web-app xmlns:xsi=& ...

  7. Spring Cloud Eureka 常用配置详解,建议收藏!

    前几天,栈长分享了 <Spring Cloud Eureka 注册中心集群搭建,Greenwich 最新版!>,今天来分享下 Spring Cloud Eureka 常用的一些参数配置及说 ...

  8. Spring声明式事务配置详解

    Spring支持编程式事务管理和声明式的事务管理. 编程式事务管理 将事务管理代码嵌到业务方法中来控制事务的提交和回滚 缺点:必须在每个事务操作业务逻辑中包含额外的事务管理代码 声明式事务管理 一般情 ...

  9. Spring MVC原理及配置详解

    Spring MVC概述: Spring MVC是Spring提供的一个强大而灵活的web框架.借助于注解,Spring MVC提供了几乎是POJO的开发模式,使得控制器的开发和测试更加简单.这些控制 ...

随机推荐

  1. 用js加密你的重要信息

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  2. canvas简单处理图片(反色处理)

    用canvas可以简单地处理图像,比如切割 灰色处理等,今天记下的是图像的反色处理. <!DOCTYPE html> <html> <head> <meta ...

  3. MFC操作excel

    环境:VS2013+office2007 头文件: #pragma once #ifndef __MYEXCEL_H_ #define __MYEXCEL_H_ #include "CApp ...

  4. border-radius详解

    语法: border-radius : none | <length>{1,4} [/ <length>{1,4} ]? 取值范围: <length>: 由浮点数字 ...

  5. iOS网络相关知识总结

    iOS网络相关知识总结 1.关于请求NSURLRequest? 我们经常讲的GET/POST/PUT等请求是指我们要向服务器发出的NSMutableURLRequest的类型; 我们可以设置Reque ...

  6. 常用prototype函数

    $("spcode").value --取得当前页面的值的value,可以赋值 $F('spcode')         --不能赋值 $!spcode             - ...

  7. SpringMVC源码剖析(四)- DispatcherServlet请求转发的实现

    SpringMVC完成初始化流程之后,就进入Servlet标准生命周期的第二个阶段,即“service”阶段.在“service”阶段中,每一次Http请求到来,容器都会启动一个请求线程,通过serv ...

  8. App.domain http->https

    App.domain = `${location.origin}/toa-mgw/rest/gateway`.replace(/http:\/\//, 'https://');

  9. linux----------ab--性能测试工具

    ab.exe –n 10000 –c 100 localhost/index.php //其中-n代表请求数,-c代表并发数

  10. activity 四种启动模式

    前言 Activity的启动模式决定了Activity的启动运行方式 四种模式 Activity启动模式设置: <activity android:name=".MainActivit ...