总:

用户通过浏览器发送URL地址,由FilterSecurityInterceptor判断是否具有相应的访问权限。
对于用户请求的方法权限,例如注解@PreAuthorize("hasRole('ADMIN')"),由MethodSecurityInterceptor判断
两个拦截器都继承了AbstractSecurityInterceptor

  1. /*
  2. * Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. package org.springframework.security.web.access.intercept;
  17. import java.io.IOException;
  18. import javax.servlet.Filter;
  19. import javax.servlet.FilterChain;
  20. import javax.servlet.FilterConfig;
  21. import javax.servlet.ServletException;
  22. import javax.servlet.ServletRequest;
  23. import javax.servlet.ServletResponse;
  24. import org.springframework.security.access.SecurityMetadataSource;
  25. import org.springframework.security.access.intercept.AbstractSecurityInterceptor;
  26. import org.springframework.security.access.intercept.InterceptorStatusToken;
  27. import org.springframework.security.web.FilterInvocation;
  28. /**
  29. * Performs security handling of HTTP resources via a filter implementation.
  30. * 通过筛选器实现对HTTP资源的安全处理。
  31. * <p>
  32. * The <code>SecurityMetadataSource</code> required by this security interceptor is of
  33. * type {@link FilterInvocationSecurityMetadataSource}.
  34. * <p>
  35. *安全拦截器所需的SecurityMetadataSource类型是FilterInvocationSecurityMetadataSource
  36. *
  37. * Refer to {@link AbstractSecurityInterceptor} for details on the workflow.
  38. * </p>
  39. *
  40. * @author Ben Alex
  41. * @author Rob Winch
  42. */
  43. public class FilterSecurityInterceptor extends AbstractSecurityInterceptor implements
  44. Filter {
  45. // ~ Static fields/initializers
  46. // =====================================================================================
  47. private static final String FILTER_APPLIED = "__spring_security_filterSecurityInterceptor_filterApplied";
  48. // ~ Instance fields
  49. // ================================================================================================
  50. /**
  51. *securityMetadataSource 中包含了一个HashMap,map中保存了用户请求的Http.Method和相应的URL地址
  52. *例如在Spring boot中,可能是如下的配置,参考图1
  53. *securityMetadataSource中的内容,参考图2
  54. */
  55. private FilterInvocationSecurityMetadataSource securityMetadataSource;
  56. private boolean observeOncePerRequest = true;
  57. // ~ Methods
  58. // ========================================================================================================
  59. /**
  60. * Not used (we rely on IoC container lifecycle services instead)
  61. *
  62. * @param arg0 ignored
  63. *
  64. * @throws ServletException never thrown
  65. */
  66. public void init(FilterConfig arg0) throws ServletException {
  67. }
  68. /**
  69. * Not used (we rely on IoC container lifecycle services instead)
  70. */
  71. public void destroy() {
  72. }
  73. /**
  74. * Method that is actually called by the filter chain. Simply delegates to the
  75. * {@link #invoke(FilterInvocation)} method.
  76. *
  77. * @param request the servlet request
  78. * @param response the servlet response
  79. * @param chain the filter chain
  80. *
  81. * @throws IOException if the filter chain fails
  82. * @throws ServletException if the filter chain fails
  83. *
  84. *
  85. *通过责任链式调用,执行doFilter方法
  86. *FilterInvocation中保存了filter相关的信息,比如request,response,chain
  87. *通过invoke方法处理具体的url过滤
  88. */
  89. public void doFilter(ServletRequest request, ServletResponse response,
  90. FilterChain chain) throws IOException, ServletException {
  91. FilterInvocation fi = new FilterInvocation(request, response, chain);
  92. invoke(fi);
  93. }
  94. public FilterInvocationSecurityMetadataSource getSecurityMetadataSource() {
  95. return this.securityMetadataSource;
  96. }
  97. public SecurityMetadataSource obtainSecurityMetadataSource() {
  98. return this.securityMetadataSource;
  99. }
  100. public void setSecurityMetadataSource(FilterInvocationSecurityMetadataSource newSource) {
  101. this.securityMetadataSource = newSource;
  102. }
  103. public Class<?> getSecureObjectClass() {
  104. return FilterInvocation.class;
  105. }
  106. public void invoke(FilterInvocation fi) throws IOException, ServletException {
  107. //获取当前http请求的地址,比如说“/login”
  108. if ((fi.getRequest() != null)
  109. && (fi.getRequest().getAttribute(FILTER_APPLIED) != null)
  110. && observeOncePerRequest) {
  111. // filter already applied to this request and user wants us to observe
  112. // once-per-request handling, so don't re-do security checking
  113. fi.getChain().doFilter(fi.getRequest(), fi.getResponse());
  114. }
  115. else {
  116. // first time this request being called, so perform security checking
  117. if (fi.getRequest() != null) {
  118. fi.getRequest().setAttribute(FILTER_APPLIED, Boolean.TRUE);
  119. }
  120. //这里做主要URL比对,将当前URL与securityMetadataSource(我们自己配置)中的URL过滤条件进行比对
  121. //首先判断当前URL是permit的还是需要验证的
  122. //若需要验证,尝试加载保存在SecurityContextHolder.getContext()中的已登录信息
  123. //调用AbstractSecurityInterceptor中的AccessDecisionManager对象的decide方法
  124. //如果对于配置中需要登录才可访问的URL,已经查找到登录信息,则执行下一个Filter
  125. InterceptorStatusToken token = super.beforeInvocation(fi);
  126. try {
  127. fi.getChain().doFilter(fi.getRequest(), fi.getResponse());
  128. }
  129. finally {
  130. super.finallyInvocation(token);
  131. }
  132. super.afterInvocation(token, null);
  133. }
  134. }
  135. /**
  136. * Indicates whether once-per-request handling will be observed. By default this is
  137. * <code>true</code>, meaning the <code>FilterSecurityInterceptor</code> will only
  138. * execute once-per-request. Sometimes users may wish it to execute more than once per
  139. * request, such as when JSP forwards are being used and filter security is desired on
  140. * each included fragment of the HTTP request.
  141. *
  142. * @return <code>true</code> (the default) if once-per-request is honoured, otherwise
  143. * <code>false</code> if <code>FilterSecurityInterceptor</code> will enforce
  144. * authorizations for each and every fragment of the HTTP request.
  145. */
  146. public boolean isObserveOncePerRequest() {
  147. return observeOncePerRequest;
  148. }
  149. public void setObserveOncePerRequest(boolean observeOncePerRequest) {
  150. this.observeOncePerRequest = observeOncePerRequest;
  151. }
  152. }

Spring security用户URL权限之FilterSecurityInterceptor的更多相关文章

  1. Spring Security 动态url权限控制(三)

    一.前言 本篇文章将讲述Spring Security 动态分配url权限,未登录权限控制,登录过后根据登录用户角色授予访问url权限 基本环境 spring-boot 2.1.8 mybatis-p ...

  2. Spring Security实现RBAC权限管理

    Spring Security实现RBAC权限管理 一.简介 在企业应用中,认证和授权是非常重要的一部分内容,业界最出名的两个框架就是大名鼎鼎的 Shiro和Spring Security.由于Spr ...

  3. 登陆模块,这个是很重要的模块,有shiro和spring security专门的权限认证框架

    登陆模块,这个是很重要的模块,有shiro和spring security专门的权限认证框架

  4. Spring Security 基于URL的权限判断

    1.  FilterSecurityInterceptor 源码阅读 org.springframework.security.web.access.intercept.FilterSecurityI ...

  5. Spring security 用户,角色,权限,资源

    转自:http://blog.csdn.net/wybqq/article/details/52940194 关于Spring security对用户请求的处理过程 体现在这两个过程的体现. 关于用户 ...

  6. spring security 登录、权限管理配置

    登录流程 1)容器启动(MySecurityMetadataSource:loadResourceDefine加载系统资源与权限列表)  2)用户发出请求  3)过滤器拦截(MySecurityFil ...

  7. 别再让你的微服务裸奔了,基于 Spring Session & Spring Security 微服务权限控制

    微服务架构 网关:路由用户请求到指定服务,转发前端 Cookie 中包含的 Session 信息: 用户服务:用户登录认证(Authentication),用户授权(Authority),用户管理(R ...

  8. Spring Security 自定义 登陆 权限验证

    转载于:https://www.jianshu.com/p/6b8fb59b614b 项目简介 基于Spring Cloud 的项目,Spring Cloud是在Spring Boot上搭建的所以按照 ...

  9. 获取spring security用户相关信息

    在JSP中获得 使用spring security的标签库 在页面中引入标签 <%@ taglib prefix="sec" uri="http://www.spr ...

随机推荐

  1. Python高级核心技术97讲 系列教程

    Python高级核心技术97讲 系列教程 整个课程都看完了,这个课程的分享可以往下看,下面有链接,之前做java开发也做了一些年头,也分享下自己看这个视频的感受,单论单个知识点课程本身没问题,大家看的 ...

  2. jQuery 图片上传

    1. 概述 1.1 说明 在一些前后端不分离的项目中,经常有一些需要把文件或者图片上传的功能,故记录此代码以便后期使用. 1.2 要求 1.上传,10M以内,限bmp,jpg,png,jpeg等图片格 ...

  3. (转)jQuery中append(),prepend()与after(),before()的区别

    在jQuery中,添加元素有append(),prepend和 after(),before()两种共四个. 根据字面意思我们可以看出他们分别是追加,添加和之前,之后,意思相近.同时他们又都有添加元素 ...

  4. $.ajax中contentType: “application/json” 的用法

    不使用contentType: “application/json”则data可以是对象 $.ajax({ url: actionurl, type: "POST", datTyp ...

  5. PHP学习(mysqli函数)

    php是一种运行在服务器端的程序语言,用于生产动态网页内容.特点:开源,简单,易上手,跨平台(windows,linux),占用资源少,尤其适合中小型应用开发.(微博,微信,论坛等等)一,搭建软件环境 ...

  6. JavaReflection(转载)

    平时看代码时,总是碰到这些即熟悉又陌生的名次,每天都与他们相见,但见面后又似曾没有任何的交集,所以今天我就来认识下这两个江湖侠客的背景: CLASS 在Java中,每个class都有一个相应的Clas ...

  7. 【JZOJ3213】【SDOI2013】直径

    ╰( ̄▽ ̄)╭ 小 Q最近学习了一些图论知识.根据课本,有如下定义. 树:无回路且连通的无向图,每条边都有正整数的权值来表示其长度.如果一棵树有N个节点,可以证明其有且仅有 N-1 条边. 路径:一棵 ...

  8. Tomcat的原理

    Tomcat是一种WEB容器:它主要实现了javaEE中Servlet.JSP规范,同时提供HTTP服务. 它主要由一个Serve服务器,Server服务器中存在多个Service服务,Service ...

  9. 洛谷2050 BZOJ2897美食节题解

    放个链接 BZ链接 其实这题就是修车的加强版,做法差不多,还是对于每个厨师进行拆点 可是这样强行建图跑网络流会T飞 我们发现,如果一个厨师没有做倒数第x到菜,他一定不会做倒数第x+1到菜 我们的每次增 ...

  10. windows.open window.location.href的用法和区别

    window.location.href  只能在当前页面打开,不能用新窗口打开 windows.open("URL","窗口名称","窗口外观设定& ...