首页 > 其他分享 >SpringSecurity过滤器之SecurityContextHolderAwareRequestFilter,RequestCacheAwareFilter

SpringSecurity过滤器之SecurityContextHolderAwareRequestFilter,RequestCacheAwareFilter

时间:2023-05-02 14:23:25浏览次数:34  
标签:HttpServletRequest null return SecurityContextHolderAwareRequestFilter public Re

SecurityContextHolderAwareRequestFilter

SecurityContextHolderAwareRequestFilter对Servelet3.0的api做了封装。

public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
		throws IOException, ServletException {
	chain.doFilter(this.requestFactory.create((HttpServletRequest) req, (HttpServletResponse) res), res);
}

requestFactory是HttpServlet3RequestFactory。

HttpServlet3RequestFactory#create

public HttpServletRequest create(HttpServletRequest request, HttpServletResponse response) {
	return new Servlet3SecurityContextHolderAwareRequestWrapper(request, this.rolePrefix, response);
}

rolePrefix是ROLE_。用于添加角色前缀。

private class Servlet3SecurityContextHolderAwareRequestWrapper extends SecurityContextHolderAwareRequestWrapper {

	private final HttpServletResponse response;

	Servlet3SecurityContextHolderAwareRequestWrapper(HttpServletRequest request, String rolePrefix,
			HttpServletResponse response) {
		super(request, HttpServlet3RequestFactory.this.trustResolver, rolePrefix);
		this.response = response;
	}

	@Override
	public AsyncContext getAsyncContext() {
		AsyncContext asyncContext = super.getAsyncContext();
		if (asyncContext == null) {
			return null;
		}
		return new SecurityContextAsyncContext(asyncContext);
	}

	@Override
	public AsyncContext startAsync() {
		AsyncContext startAsync = super.startAsync();
		return new SecurityContextAsyncContext(startAsync);
	}

	@Override
	public AsyncContext startAsync(ServletRequest servletRequest, ServletResponse servletResponse)
			throws IllegalStateException {
		AsyncContext startAsync = super.startAsync(servletRequest, servletResponse);
		return new SecurityContextAsyncContext(startAsync);
	}

	@Override
	public boolean authenticate(HttpServletResponse response) throws IOException, ServletException {
		AuthenticationEntryPoint entryPoint = HttpServlet3RequestFactory.this.authenticationEntryPoint;
		if (entryPoint == null) {
			HttpServlet3RequestFactory.this.logger.debug(
					"authenticationEntryPoint is null, so allowing original HttpServletRequest to handle authenticate");
			return super.authenticate(response);
		}
		if (isAuthenticated()) {
			return true;
		}
		entryPoint.commence(this, response,
				new AuthenticationCredentialsNotFoundException("User is not Authenticated"));
		return false;
	}

	@Override
	public void login(String username, String password) throws ServletException {
		if (isAuthenticated()) {
			throw new ServletException("Cannot perform login for '" + username + "' already authenticated as '"
					+ getRemoteUser() + "'");
		}
		AuthenticationManager authManager = HttpServlet3RequestFactory.this.authenticationManager;
		if (authManager == null) {
			HttpServlet3RequestFactory.this.logger.debug(
					"authenticationManager is null, so allowing original HttpServletRequest to handle login");
			super.login(username, password);
			return;
		}
		Authentication authentication = getAuthentication(authManager, username, password);
		SecurityContext context = SecurityContextHolder.createEmptyContext();
		context.setAuthentication(authentication);
		SecurityContextHolder.setContext(context);
	}

	private Authentication getAuthentication(AuthenticationManager authManager, String username, String password)
			throws ServletException {
		try {
			UsernamePasswordAuthenticationToken authentication = UsernamePasswordAuthenticationToken
					.unauthenticated(username, password);
			Object details = HttpServlet3RequestFactory.this.authenticationDetailsSource.buildDetails(this);
			authentication.setDetails(details);
			return authManager.authenticate(authentication);
		}
		catch (AuthenticationException ex) {
			SecurityContextHolder.clearContext();
			throw new ServletException(ex.getMessage(), ex);
		}
	}

	@Override
	public void logout() throws ServletException {
		List<LogoutHandler> handlers = HttpServlet3RequestFactory.this.logoutHandlers;
		if (CollectionUtils.isEmpty(handlers)) {
			HttpServlet3RequestFactory.this.logger
					.debug("logoutHandlers is null, so allowing original HttpServletRequest to handle logout");
			super.logout();
			return;
		}
		Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
		for (LogoutHandler handler : handlers) {
			handler.logout(this, this.response, authentication);
		}
	}

	private boolean isAuthenticated() {
		return getUserPrincipal() != null;
	}

}

Servlet3SecurityContextHolderAwareRequestWrapper对Servlet3.0的方法做了封装。方法中有AsyncContext的是与异步web相关。对Servlet3.0的登录,登出,认证方法都做了封装。父类SecurityContextHolderAwareRequestWrapper重写了HttpServletRequestWrapper的getUserPrincipal(),isUserInRole(String),getRemoteUser()。

RequestCacheAwareFilter

public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
		throws IOException, ServletException {
	HttpServletRequest wrappedSavedRequest = this.requestCache.getMatchingRequest((HttpServletRequest) request,
			(HttpServletResponse) response);
	chain.doFilter((wrappedSavedRequest != null) ? wrappedSavedRequest : request, response);
}

如果在requestCache有保存的请求直接用否则用ServletRequest。默认是HttpSessionRequestCache。将SavedRequest保存到Session中。

标签:HttpServletRequest,null,return,SecurityContextHolderAwareRequestFilter,public,Re
From: https://www.cnblogs.com/shigongp/p/17367617.html

相关文章

  • springSecurity过滤器之AnonymousAuthenticationFilter
    SpringSecurity提供了匿名登录功能,让我们不登录也能访问。比如/anoy路径及子路径都能匿名访问,配置如下:@ConfigurationpublicclassMySecurityConfigextendsWebSecurityConfigurerAdapter{@Overrideprotectedvoidconfigure(HttpSecurityhttp)throwsException......
  • SpringSecurity过滤器之SecurityContextPersistenceFilter
    SecurityContextPersistenceFilter在请求之前从配置的SecurityContextRepository获得的信息填充SecurityContextHolder,并在请求完成并清除上下文holder后将其存储回存储库。默认情况下,它使用HttpSessionSecurityContextRepository。privatevoiddoFilter(HttpServletRequestreq......
  • SpringSecurity过滤器之SessionManagementFilter
    SessionManagementFilter检测用户自请求开始以来是否已通过身份验证,如果已通过,则调用SessionAuthenticationStrategy以执行任何与会话相关的活动,例如激活会话固定保护机制或检查多个并发登录。配置如下:@ConfigurationpublicclassMySecurityConfigextendsWebSecurityConfigur......
  • SpringBoot SpringSecurity 介绍(基于内存的验证)
    SpringBoot集成SpringSecurity+MySQL+JWT附源码,废话不多直接盘SpringBoot已经为用户采用默认配置,只需要引入pom依赖就能快速启动SpringSecurity。目的:验证请求用户的身份,提供安全访问优势:基于Spring,配置方便,减少大量代码内置访问控制方法permitAll()表示所匹配的......
  • SpringBoot 集成 SpringSecurity + MySQL + JWT 附源码,废话不多直接盘
    SpringBoot集成SpringSecurity+MySQL+JWT无太多理论,直接盘一般用于Web管理系统可以先看SpringBootSpringSecurity基于内存的使用介绍本文介绍如何整合SpringSecurity+MySQL+JWT数据结构数据库脚本:https://gitee.com/VipSoft/VipBoot/blob/develop/vipsoft-sec......
  • SpringSecurity从入门到精通:认证成功处理器&认证失败处理器
    认证成功处理器  认证失败处理器  ......
  • SpringSecurity从入门到精通:其他权限校验方法&自定义权限校验方法
    其他权限校验方法我们前面都是使用@PreAuthorize注解,然后在在其中使用的是hasAuthority方法进行校验。SpringSecurity还为我们提供了其它方法例如:hasAnyAuthority,hasRole,hasAnyRole等。​这里我们先不急着去介绍这些方法,我们先去理解hasAuthority的原理,然后再去学......
  • SpringSecurity从入门到精通:从数据库查询权限信息&自定义失败处理
    从数据库查询权限信息      记得打开redis      自定义失败处理我们还希望在认证失败或者是授权失败的情况下也能和我们的接口一样返回相同结构的json,这样可以让前端能对响应进行统一的处理。要实现这个功能我们需要知道SpringSecurity......
  • SpringSecurity从入门到精通:授权基本流程&设置资源所需权限&封装权限信息
    授权基本流程在SpringSecurity中,会使用默认的FilterSecurityInterceptor来进行权限校验,在FilterSecurityInterceptor中会从SecurityContextHilder获取其中的Authentication,然后获取其中的权限信息,当前用户是否拥有访问当前资源所需的权限所以我们在项目中只需要把当前登......
  • SpringSecurity从入门到精通:认证配置详解&权限系统的作用
    认证配置详解Configpackagecom.sangeng.config;importcom.sangeng.filter.JwtAuthenticationTokenFilter;importorg.springframework.beans.factory.annotation.Autowired;importorg.springframework.context.annotation.Bean;importorg.springframework.context.ann......