Spring security用户URL权限FilterSecurityInterceptor使用解析

网友投稿 688 2023-07-06

Spring security用户URL权限FilterSecurityInterceptor使用解析

Spring security用户URL权限FilterSecurityInterceptor使用解析

这篇文章主要介绍了Spring security用户URL权限FilterSecurityInterceptor使用解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下

用户通过浏览器发送URL地址,由FilterSecurityInterceptor判断是否具有相应的访问权限。

对于用户请求的方法权限,例如注解@PreAuthorize("hasRole('ADMIN')"),由MethodSecurityInterceptor判断

两个-都继承了AbstractSecurityInterceptor

代码如下

/*

* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited

*

* Licensed under the Apache License, Version 2.0 (the "License");

* you may not use this file except in compliance with the License.

* You may obtain a copy of the License at

*

* http://apache.org/licenses/LICENSE-2.0

*

* Unless required by applicable law or agreed to in writing, software

* distributed under the License is distributed on an "AS IS" BASIS,

* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

* See the License for the specific language governing permissions and

* limitations under the License.

*/

package org.springframework.security.web.access.intercept;

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.AbstractSecurityIntercepthttp://or;

import org.springframework.security.access.intercept.InterceptorStatusToken;

import org.springframework.security.web.FilterInvocation;

/**

* Performs security handling of HTTP resources via a filter implementation.

* 通过筛选器实现对HTTP资源的安全处理。

*

* The SecurityMetadataSource required by this security interceptor is of

* type {@link FilterInvocationSecurityMetadataSource}.

*

*安全-所需的SecurityMetadataSource类型是FilterInvocationSecurityMetadataSource

*

* Refer to {@link AbstractSecurityInterceptor} for details on the workflow.

*

*

* @author Ben Alex

* @author Rob Winch

*/

public class FilterSecurityInterceptor extends AbstractSecurityInterceptor implements

Filter {

// ~ Static fields/initializers

// =====================================================================================

private static final String FILTER_APPLIED = "__spring_security_filterSecurityInterceptor_filterApplied";

// ~ Instance fields

// ================================================================================================

/**

*securityMetadataSource 中包含了一个HashMap,map中保存了用户请求的Http.Method和相应的URL地址

*例如在Spring boot中,可能是如下的配置,参考图1

*securityMetadataSource中的内容,参考图2

*/

privateLOxVYmFm FilterInvocationSecurityMetadataSource securityMetadataSource;

private Boolean observeOncePerRequest = true;

// ~ Methods

// ========================================================================================================

/**

* Not used (we rely on IoC container lifecycle services instead)

*

* @param arg0 ignored

*

* @throws ServletException never thrown

*/

public void init(FilterConfig arg0) throws ServletException {

}

/**

* Not used (we rely on IoC container lifecycle services instead)

*/

public void destroy() {

}

/**

* Method that is actually called by the filter chain. Simply delegates to the

* {@link #invoke(FilterInvocation)} method.

*

* @param request the servlet request

* @param response the servlet response

* @param chain the filter chain

*

* @throws IOException if the filter chain fails

* @throws ServletException if the filter chain fails

*

*

*通过责任链式调用,执行doFilter方法

*FilterInvocation中保存了filter相关的信息,比如request,response,chain

*通过invoke方法处理具体的url过滤

*/

public void doFilter(ServletRequest request, ServletResponse response,

FilterChain chain) throws IOException, ServletException {

FilterInvocation fi = new FilterInvocation(request, response, chain);

invoke(fi);

}

public FilterInvocationSecurityMetadataSource getSecurityMetadataSource() {

return this.securityMetadataSource;

}

public SecurityMetadataSource obtainSecurityMetadataSource() {

return this.securityMetadataSource;

}

public void setSecurityMetadataSource(FilterInvocationSecurityMetadataSource newSource) {

this.securityMetadataSource = newSource;

}

public Class> getSecureObjectClass() {

return FilterInvocation.class;

}

public void invoke(FilterInvocation fi) throws IOException, ServletException {

//获取当前http请求的地址,比如说“/login”

if ((fi.getRequest() != null)

&& (fi.getRequest().getAttribute(FILTER_APPLIED) != null)

&& observeOncePerRequest) {

// filter already applied to this request and user wants us to observe

// once-per-request handling, so don't re-do security checking

fi.getChain().doFilter(fi.getRequest(), fi.getResponse());

} else {

// first time this request being called, so perform security checking

if (fi.getRequest() != null) {

fi.getRequest().setAttribute(FILTER_APPLIED, Boolean.TRUE);

}

//这里做主要URL比对,将当前URL与securityMetadataSource(我们自己配置)中的URL过滤条件进行比对

//首先判断当前URL是permit的还是需要验证的

//若需要验证,尝试加载保存在SecurityContextHolder.getContext()中的已登录信息

//调用AbstractSecurityInterceptor中的AccessDecisionManager对象的decide方法

//如果对于配置中需要登录才可访问的URL,已经查找到登录信息,则执行下一个Filter

InterceptorStatusToken token = super.beforeInvocation(fi);

try {

fi.getChain().doFilter(fi.getRequest(), fi.getResponse());

}

finally {

super.finallyInvocation(token);

}

super.afterInvocation(token, null);

}

}

/**

* Indicates whether once-per-request handling will be observed. By default this is

* true, meaning the FilterSecurityInterceptor will only

* execute once-per-request. Sometimes users may wish it to execute more than once per

* request, such as when jsP forwards are being used and filter security is desired on

* each included fragment of the HTTP request.

*

* @return true (the default) if once-per-request is honoured, otherwise

* false if FilterSecurityInterceptor will enforce

* authorizations for each and every fragment of the HTTP request.

*/

public Boolean isObserveOncePerRequest() {

return observeOncePerRequest;

}

public void setObserveOncePerRequest(Boolean observeOncePerRequest) {

this.observeOncePerRequest = observeOncePerRequest;

}

}

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:如何使用SpEL表达式实现动态分表查询
下一篇:Spring Security如何使用URL地址进行权限控制
相关文章

 发表评论

暂时没有评论,来抢沙发吧~