前往小程序,Get更优阅读体验!
立即前往
社区首页 >专栏 >Springsecurity之LogoutFilter

Springsecurity之LogoutFilter

作者头像
克虏伯
发布于 2019-04-15 02:21:56
发布于 2019-04-15 02:21:56
1.2K00
代码可运行
举报
运行总次数:0
代码可运行

    注:Springsecurity版本4.3.x.RELEASE

    先上一张LogoutFilter的类继承图,如下图1所示,原图见我的Github

                                                               图1     

    LogoutFilter和其它Springsecurity的Filter一样,都是继承自GenericFilterBean。

    来看下LogoutFilter的属性和构造方法,如下List-1所示。当我们定义了如List-2所示的bean时,调用的是List-1中的第二个构造方法。

List-1

代码语言:javascript
代码运行次数:0
复制
public class LogoutFilter extends GenericFilterBean {
	private RequestMatcher logoutRequestMatcher;
	private final LogoutHandler handler;
	private final LogoutSuccessHandler logoutSuccessHandler;

	/**
	 * Constructor which takes a <tt>LogoutSuccessHandler</tt> instance to determine the
	 * target destination after logging out. The list of <tt>LogoutHandler</tt>s are
	 * intended to perform the actual logout functionality (such as clearing the security
	 * context, invalidating the session, etc.).
	 */
	public LogoutFilter(LogoutSuccessHandler logoutSuccessHandler,
			LogoutHandler... handlers) {
		this.handler = new CompositeLogoutHandler(handlers);
		Assert.notNull(logoutSuccessHandler, "logoutSuccessHandler cannot be null");
		this.logoutSuccessHandler = logoutSuccessHandler;
		setFilterProcessesUrl("/logout");
	}

	public LogoutFilter(String logoutSuccessUrl, LogoutHandler... handlers) {
		this.handler = new CompositeLogoutHandler(handlers);
		Assert.isTrue(
				!StringUtils.hasLength(logoutSuccessUrl)
						|| UrlUtils.isValidRedirectUrl(logoutSuccessUrl),
				() -> logoutSuccessUrl + " isn't a valid redirect URL");
		SimpleUrlLogoutSuccessHandler urlLogoutSuccessHandler = new SimpleUrlLogoutSuccessHandler();
		if (StringUtils.hasText(logoutSuccessUrl)) {
			urlLogoutSuccessHandler.setDefaultTargetUrl(logoutSuccessUrl);
		}
		logoutSuccessHandler = urlLogoutSuccessHandler;
		setFilterProcessesUrl("/logout");
	}

List-2

代码语言:javascript
代码运行次数:0
复制
<bean id="requestSingleLogoutFilter" class="org.springframework.security.web.authentication.logout.LogoutFilter">
	<constructor-arg value="https://localhost:9443/cas/logout"/>
	<constructor-arg>
		<bean class="org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler"/>
	</constructor-arg>
	<property name="filterProcessesUrl" value="/logout/cas"/>
</bean>

    来看下LogoutFilter的doFilter方法,如下List-3所示,

List-3

代码语言:javascript
代码运行次数:0
复制
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
	HttpServletRequest request = (HttpServletRequest) req;
	HttpServletResponse response = (HttpServletResponse) res;
	if (requiresLogout(request, response)) {
		Authentication auth = SecurityContextHolder.getContext().getAuthentication();
		if (logger.isDebugEnabled()) {
			logger.debug("Logging out user '" + auth + "' and transferring to logout destination");
		}
		this.handler.logout(request, response, auth);
		logoutSuccessHandler.onLogoutSuccess(request, response, auth);
		return;
	}
	chain.doFilter(request, response);
}

     在List-3中:

  1. requiresLogout方法判断requst中的url是否是/logout/cas,见List-2中的属性filterProcessesUrl
  2. 如果满足步骤1的要求,那么调用LogoutHandler的logout方法,会将Session失效,此外将SecurityContextHolder清空
  3. 如果满足步骤1的要求,那么调用LogoutSuccessHandler的onLogoutSuccess方法,设置HttpServletResponse的重定向
  4. 如果满足步骤1的要求,那么不会调用FilterChain了

    来看下SecurityContextLogoutHandler的logout方法,如下List-4所示,

List-4

代码语言:javascript
代码运行次数:0
复制
public void logout(HttpServletRequest request, HttpServletResponse response, Authentication authentication) {
	Assert.notNull(request, "HttpServletRequest required");
	if (invalidateHttpSession) {
		HttpSession session = request.getSession(false);
		if (session != null) {
			logger.debug("Invalidating session: " + session.getId());
			session.invalidate();
		}
	}
	if (clearAuthentication) {
		SecurityContext context = SecurityContextHolder.getContext();
		context.setAuthentication(null);
	}
	SecurityContextHolder.clearContext();
}

    在List-4中:

  1. 会将HttpSession失效
  2. 清空SecurityContextHolder的context

    来看下SimpleUrlLogoutSuccessHandler,如图2和List-5所示,它直接调用父类AbstractAuthenticationTargetUrlRequestHandler的handle方法,看List-6所示,方法determineTargetUrl决定使用哪个targetUrl;List-6中handle方法的redirectStrategy.sendRedirect(request, response, targetUrl),调用的DefaultRedirectStrategy的sendRedirect方法,如List-7所示,最终调用的是response的sendRedirect方法。

                                                                图2

List-5

代码语言:javascript
代码运行次数:0
复制
public class SimpleUrlLogoutSuccessHandler extends
		AbstractAuthenticationTargetUrlRequestHandler implements LogoutSuccessHandler {

	public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response,
			Authentication authentication) throws IOException, ServletException {
		super.handle(request, response, authentication);
	}
}

List-6

代码语言:javascript
代码运行次数:0
复制
protected void handle(HttpServletRequest request, HttpServletResponse response,
		Authentication authentication) throws IOException, ServletException {
	String targetUrl = determineTargetUrl(request, response);
	if (response.isCommitted()) {
		logger.debug("Response has already been committed. Unable to redirect to "
				+ targetUrl);
		return;
	}
	redirectStrategy.sendRedirect(request, response, targetUrl);
}

/**
 * Builds the target URL according to the logic defined in the main class Javadoc.
 */
protected String determineTargetUrl(HttpServletRequest request,
		HttpServletResponse response) {
	if (isAlwaysUseDefaultTargetUrl()) {
		return defaultTargetUrl;
	}
	// Check for the parameter and use that if available
	String targetUrl = null;
	if (targetUrlParameter != null) {
		targetUrl = request.getParameter(targetUrlParameter);
		if (StringUtils.hasText(targetUrl)) {
			logger.debug("Found targetUrlParameter in request: " + targetUrl);
			return targetUrl;
		}
	}
	if (useReferer && !StringUtils.hasLength(targetUrl)) {
		targetUrl = request.getHeader("Referer");
		logger.debug("Using Referer header: " + targetUrl);
	}
	if (!StringUtils.hasText(targetUrl)) {
		targetUrl = defaultTargetUrl;
		logger.debug("Using default Url: " + targetUrl);
	}
	return targetUrl;
}

List-7

代码语言:javascript
代码运行次数:0
复制
public void sendRedirect(HttpServletRequest request, HttpServletResponse response,
		String url) throws IOException {
	String redirectUrl = calculateRedirectUrl(request.getContextPath(), url);
	redirectUrl = response.encodeRedirectURL(redirectUrl);

	if (logger.isDebugEnabled()) {
		logger.debug("Redirecting to '" + redirectUrl + "'");
	}

	response.sendRedirect(redirectUrl);
}

(adsbygoogle = window.adsbygoogle || []).push({});

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2018/11/12 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
Spring Security源码分析之LogoutFilter
LogoutFilter过滤器对应的类路径为 org.springframework.security.web.authentication.logout.LogoutFilter 通过这个类的源
JavaEdge
2018/05/16
1.2K0
Spring Security源码分析八:Spring Security 退出
Spring Security的退出请求(默认为/logout)由LogoutFilter过滤器拦截处理。
java干货
2021/02/19
6890
Spring Security源码分析八:Spring Security 退出
Spring Security 实战干货:实现自定义退出登录
上一篇对 Spring Security 所有内置的 Filter 进行了介绍。今天我们来实战如何安全退出应用程序。
码农小胖哥
2019/12/05
2.7K0
Spring Security学习(二)
被LogoutFilter在成功注销后调用,用来进行重定向或者转发相应的目的地。注意这个接口与LogoutHandler几乎一样,但是可以抛出异常。
allsmallpig
2021/02/25
8420
Springsecurity之FilterChainProxy
    最近在使用Springsecurity,然后debug代码时,经常看到FilterChainProxy,所以就在这里记录下吧。
克虏伯
2019/04/15
7290
Springsecurity之FilterChainProxy
Springsecurity-oauth2之/oauth/token的处理
    Springsecurity-oauth2的版本是2.2.1.RELEASE.
克虏伯
2019/04/15
2K0
Springsecurity-oauth2之/oauth/token的处理
Springsecurity之ExceptionTranslationFilter
    Springsecurity的版本是4.3.x,源码可以在Github上下载。
克虏伯
2019/04/15
2.3K0
Springsecurity之ExceptionTranslationFilter
springsecurity 表单登录
springSecurity需要自定义配置值 基本都是继承WebSecurityConfigurerAdapter
周杰伦本人
2022/10/25
6830
Spring Security 实战 - 退出原理实现源码分析
Spring Security的退出请求(默认为/logout)由LogoutFilter过滤器拦截处理
JavaEdge
2018/12/14
1.4K0
Spring Security 实战 - 退出原理实现源码分析
SpringFramework之mvc的HandlerMapping
    我们从DispatcherServlet的doDispatch方法说起,如下List-2,getHandler(processedRequest)会调用RequestMappingHandlerMapping实例的getHandler方法。
克虏伯
2019/07/01
5000
SpringFramework之mvc的HandlerMapping
Springsecurity之AuthenticationEntryPoint
    org.springframework.security.web.AuthenticationEntryPoint在spring-security-web里面,分析的版本是5.0。
克虏伯
2019/04/15
4.3K0
Spring Security---退出功能详解
其实使用Spring Security进行logout非常简单,只需要在spring Security配置类配置项上加上这样一行代码:http.logout()。关于spring Security配置类的其他很多实现、如:HttpBasic模式、formLogin模式、自定义登录验证结果、使用权限表达式、session会话管理,。本节的核心内容就是在原有配置的基础上,加上这样一行代码:http.logout()。
大忽悠爱学习
2021/12/07
2.2K0
Spring Security---退出功能详解
SpringSecurity6 | 核心过滤器
大家好,我是Leo哥🫣🫣🫣,上一节我们通过源码剖析以及图文分析,了解了关于委派筛选器代理和过滤器链代理的原理和作用。这节课我们接着学习SpringSecurity的过滤器,了解SpringSecurity中都有哪些核心过滤器。好了,话不多说让我们开始吧😎😎😎。
程序员Leo
2023/11/17
9200
SpringSecurity6 | 核心过滤器
ruoyi-vue版本(四)@PreAuthorize 注解在若依里面的作用,springsecurity 框架相关的配置
我们打开若依项目,发现一些接口上面是有@PreAuthorize 注解,那么这个注解的作用是什么?
一写代码就开心
2023/02/01
9630
SpringFramework之HandlerInterceptor
    最近在使用Spring时,总感觉对HandlerInterceptor有点模糊,回头再来看看,记录下。
克虏伯
2019/04/15
7810
SpringFramework之HandlerInterceptor
Spring Security笔记:自定义Login/Logout Filter、AuthenticationProvider、AuthenticationToken
在前面的学习中,配置文件中的<http>...</http>都是采用的auto-config="true"这种自动配置模式,根据Spring Security文档的说明: ------------------ auto-config Automatically registers a login form, BASIC authentication, logout services. If set to "true", all of these capabilities are added (althoug
菩提树下的杨过
2018/01/19
3K0
Spring Security笔记:自定义Login/Logout Filter、AuthenticationProvider、AuthenticationToken
Springsecurity-oauth2之OAuth2AuthenticationProcessingFilter
    如下图1所示,继承了Filter,还继承了InitializingBean,这个与SpringIOC有关,在创建Bean的时候,会调用afterPropertiesSet方法,进行一些判断或者初始化之类的操作
克虏伯
2019/04/15
2.4K0
Springsecurity-oauth2之OAuth2AuthenticationProcessingFilter
SpringFramework之DispatcherServlet的初始化简析
                                                           图1 DispatchServlet的类继承图
克虏伯
2019/04/15
6650
SpringFramework之DispatcherServlet的初始化简析
Spring Security内置过滤器详解
根据前面的示例,我们已经知道启动时会加载18个过滤器,并且已经知道了请求会匹配到DefaultSecurityFilterChain并依次通过这18个过滤器。
阿提说说
2022/12/02
1.1K0
聊聊SecurityContextPersistenceFilter
本文主要研究下SecurityContextPersistenceFilter的作用。
code4it
2018/09/17
7680
相关推荐
Spring Security源码分析之LogoutFilter
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验