java

关注公众号 jb51net

关闭
首页 > 软件编程 > java > Spring Security  整体架构

Spring Security  整体架构操作流程

作者:01空间

这篇文章主要介绍了Spring Security  整体架构操作流程,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧

Spring Security 整体架构

前提

开源项目一手文档基本都在github,标准文档基本都在官网。
最好的文档就是官网;
在前些年,Apache下还有个比较流行的权限框架 Shiro,但是随着Spring Security (以下简称 Security)的流行,逐渐边缘化。其实这类框架整体设计都大差不差,都是基于一系列的过滤器或者其他拦截手段实现增强。

整体架构

Servlet 整体的过滤器模型

这一块属于 Servlet 基础,过滤器算是Servlet核心功能之一,需重点掌握。

Security 过滤器链

Security 在 Servlet 过滤器上定义了一个 自己的过滤器(这个过滤器使用了委托者设计模式)

可以看到,Servlet 过滤器链上,不仅有 Security 的过滤器还有 Spring Boot 的一些过滤器,但是这里我们重点关注圈起来的那个过滤器(链)
再对比官方的这个图

就更好理解了。

自定义过滤器

我们自定义的过滤器基本都是在 Security 这个过滤器链上面的,通过编排不同的顺序,实现想要的功能。
在这之前,我们先看看Security默认的过滤器链上有哪些过滤器官方列表
这里为了照顾,访问不了官网的,简单截个图。

但不是所有过滤器默认都开启了的。

上面那个链是,Spring 全局的过滤器链,里面第四个过滤器委托给了下面那个 Security 的过滤器链,在 Security 的过滤器链中,可以看到默认有14个过滤器。
其中有几个重点关注的是:

其他的过滤器根据自己的需求,调整。

实际开发解决方案

在实际开发中,目前通常采用前后端分离的形式;有的前端对Cookie 不太友好;因此,为了统一,大部分开发者会采用 header 认证方式。
这样实现起码会有两个点需要调整

1.调整默认认证成功的处理方式
默认配置下,认证成功会跳转到一个指定的页面;现在大多会把这个跳转交给前端。

2.改为header 传递认证参数后,默认的过滤器就不支持了,需要定义一个 过滤器,解析header,并进行认证;个人推荐将这个认证过滤器放在
AnonymousAuthenticationFilter 的前面,因为前面还有些其他认证过滤器,如果自定义的过滤器太靠前,可能会被其他认证过滤器(比如上面提到的 SecurityContextPersistenceFilter 以及 SecurityContextHolderFilter)给覆盖掉认证信息,当然这要取决实际的优先级,万一你就想自定义的认证认证过滤器优先级低一点呢

可以看到,这两个认证过滤器不管你是否已经认证,会直接覆盖掉认证信息。

一个替代cookie认证的filter

提供一个简单实现,具体业务逻辑,开发者自己填充

package authorization.filter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.util.StringUtils;
import org.springframework.web.filter.OncePerRequestFilter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Collections;
public class JwtAuthenticationFilter extends OncePerRequestFilter {
	private final Logger logger = LoggerFactory.getLogger(JwtAuthenticationFilter.class);
	@Override
	protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
			throws ServletException, IOException {
		String token = request.getHeader("token");
		if (!StringUtils.hasText(token)) {
			filterChain.doFilter(request, response);
			return;
		}
		try {
			UsernamePasswordAuthenticationToken authenticationToken
					= UsernamePasswordAuthenticationToken.authenticated("zhangsan", "zs", Collections.emptyList());
			SecurityContext context = SecurityContextHolder.createEmptyContext();
			context.setAuthentication(authenticationToken);
			SecurityContextHolder.setContext(context);
			filterChain.doFilter(request, response);
		}
		finally {
			SecurityContextHolder.clearContext();
		}
	}
	@Override
	protected boolean shouldNotFilterErrorDispatch() {
		return true;
	}
}

其他组件,后续抽时间再整理整理

到此这篇关于Spring Security 整体架构的文章就介绍到这了,更多相关Spring Security 整体架构内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文