Spring Security Web : HttpSessionCsrfTokenRepository

该博客介绍了一个基于保存的存储库实现,它具备保存、提取以及生成随机值等能力,还提及了继承关系和使用方法,给出了 Spring Security Web 5.1.4.RELEASE 版本的源代码及参考文章。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

概述

介绍

HttpSessionCsrfTokenRepository是一个基于HttpSession保存csrf token的存储库实现。它具有如下能力:

  • saveToken 保存csrf tokenhttp session
  • loadTokenhttp session中提取csrf token
  • generateToken 生成csrf token,值为一个随机UUID

继承关系

HttpSessionCsrfTokenRepository

使用

public final class CsrfConfigurer<H extends HttpSecurityBuilder<H>>
		extends AbstractHttpConfigurer<CsrfConfigurer<H>, H> {
	private CsrfTokenRepository csrfTokenRepository = new LazyCsrfTokenRepository(
			new HttpSessionCsrfTokenRepository());
    // ...            
 }            

源代码

源代码版本 Spring Security Web 5.1.4.RELEASE

package org.springframework.security.web.csrf;

import java.util.UUID;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.springframework.util.Assert;

/**
 * A CsrfTokenRepository that stores the CsrfToken in the HttpSession.
 *
 * @author Rob Winch
 * @since 3.2
 */
public final class HttpSessionCsrfTokenRepository implements CsrfTokenRepository {
    
	private static final String DEFAULT_CSRF_PARAMETER_NAME = "_csrf";

	private static final String DEFAULT_CSRF_HEADER_NAME = "X-CSRF-TOKEN";

	private static final String DEFAULT_CSRF_TOKEN_ATTR_NAME = 
						HttpSessionCsrfTokenRepository.class
						.getName().concat(".CSRF_TOKEN");

    // 将 csrf token 保存在请求参数中时,使用的参数名称
	private String parameterName = DEFAULT_CSRF_PARAMETER_NAME;

    // 将 csrf token 保存在HTTP头部时,使用的头部名称
	private String headerName = DEFAULT_CSRF_HEADER_NAME;

    // 将 csrf token 保存在 http session 中时使用的属性名称
	private String sessionAttributeName = DEFAULT_CSRF_TOKEN_ATTR_NAME;


    // 保存 csrf token 到当前请求对应的 http session 中
	public void saveToken(CsrfToken token, HttpServletRequest request,
			HttpServletResponse response) {
		if (token == null) {
           // 如果将要保存的 csrf token 为 null,则获取当前 session,清除其中的
           // csrf token 属性
			HttpSession session = request.getSession(false);
			if (session != null) {
				session.removeAttribute(this.sessionAttributeName);
			}
		}
		else {
          // 如果将要保存的 csrf token 不为 null, 则获取将当前 session,将
          // csrf token 保存到其中
			HttpSession session = request.getSession();
			session.setAttribute(this.sessionAttributeName, token);
		}
	}


    // 从当前 http session 中获取所保存的 csrf token
	public CsrfToken loadToken(HttpServletRequest request) {
		HttpSession session = request.getSession(false);
		if (session == null) {
			return null;
		}
		return (CsrfToken) session.getAttribute(this.sessionAttributeName);
	}



    // 针对当前请求生成一个 csrf token 对象 CsrfToken, 实现类使用 DefaultCsrfToken,
    // 这里设置了该 CsrfToken 在头部中保存时的名称为 this.headerName, 在参数中保存时
    // 的名称为 this.parameterName,csrf token 的值为一个随机 UUID 的字符串值
	public CsrfToken generateToken(HttpServletRequest request) {
		return new DefaultCsrfToken(this.headerName, this.parameterName,
				createNewToken());
	}

	/**
	 * Sets the HttpServletRequest parameter name that the CsrfToken is
	 * expected to appear on
	 * @param parameterName the new parameter name to use
	 */
	public void setParameterName(String parameterName) {
		Assert.hasLength(parameterName, "parameterName cannot be null or empty");
		this.parameterName = parameterName;
	}

	/**
	 * Sets the header name that the CsrfToken is expected to appear on and the
	 * header that the response will contain the CsrfToken.
	 *
	 * @param headerName the new header name to use
	 */
	public void setHeaderName(String headerName) {
		Assert.hasLength(headerName, "headerName cannot be null or empty");
		this.headerName = headerName;
	}

	/**
	 * Sets the HttpSession attribute name that the CsrfToken is stored in
	 * @param sessionAttributeName the new attribute name to use
	 */
	public void setSessionAttributeName(String sessionAttributeName) {
		Assert.hasLength(sessionAttributeName,
				"sessionAttributename cannot be null or empty");
		this.sessionAttributeName = sessionAttributeName;
	}

    // 产生一个 csrf token 的值,其实是一个随机 UUID 的字符串形式
	private String createNewToken() {
		return UUID.randomUUID().toString();
	}
}

参考文章

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值