浏览wap网站,郑州市城乡建设局网站,西安个人做企业网站,wordpress yahoo主题文章目录 前言过滤器介绍用户信息的存储获取用户信息存储用户信息获取用户信息 处理逻辑总结 前言
SecurityContextHolder#xff0c;这个是一个非常基础的对象#xff0c;存储了当前应用的上下文SecurityContext#xff0c;而在SecurityContext可以获取Authentication对象… 文章目录 前言过滤器介绍用户信息的存储获取用户信息存储用户信息获取用户信息 处理逻辑总结 前言
SecurityContextHolder这个是一个非常基础的对象存储了当前应用的上下文SecurityContext而在SecurityContext可以获取Authentication对象。也就是当前认证的相关信息会存储在Authentication对象中。 默认情况下SecurityContextHolder是通过 ThreadLocal来存储对应的信息的。也就是在一个线程中我们可以通过这种方式来获取当前登录的用户的相关信息。而在SecurityContext中就只提供了对Authentication对象操作的方法。
在项目中可以通过以下方式获取当前登录的用户信息 public String hello(){Authentication authentication SecurityContextHolder.getContext().getAuthentication();Object principal authentication.getPrincipal();if(principal instanceof UserDetails){UserDetails userDetails (UserDetails) principal;System.out.println(userDetails.getUsername());return 当前登录的账号是 userDetails.getUsername();}return 当前登录的账号-- principal.toString();}调用 getContext()返回的对象是 SecurityContext接口的一个实例这个对象就是保存在线程中的。接下来将看到Spring Security中的认证大都返回一个 UserDetails的实例作为principa。
过滤器介绍
在Session中维护一个用户的安全信息就是这个过滤器处理的。从request中获取session从Session中取出已认证用户的信息保存在SecurityContext中提高效率避免每一次请求都要解析用户认证信息方便接下来的filter直接获取当前的用户信息。
用户信息的存储
用户信息的存储是通过SecutiryContextRepository接口操作的定义了对SecurityContext的存储操作在该接口中定义了如下的几个方法
public interface SecurityContextRepository {/*** 获取SecurityContext对象*/SecurityContext loadContext(HttpRequestResponseHolder requestResponseHolder);/*** 存储SecurityContext*/void saveContext(SecurityContext context, HttpServletRequest request, HttpServletResponse response);/*** 判断是否存在SecurityContext对象*/boolean containsContext(HttpServletRequest request);}默认的实现是HttpSessionSecurityContextRepository。也就是把SecurityContext存储在了HttpSession中。对应的抽象方法实现如下
获取用户信息 public SecurityContext loadContext(HttpRequestResponseHolder requestResponseHolder) {// 获取对有的Request和Response对象HttpServletRequest request requestResponseHolder.getRequest();HttpServletResponse response requestResponseHolder.getResponse();// 获取HttpSession对象HttpSession httpSession request.getSession(false);// 从HttpSession中获取SecurityContext对象SecurityContext context readSecurityContextFromSession(httpSession);if (context null) {// 如果HttpSession中不存在SecurityContext对象就创建一个// SecurityContextHolder.createEmptyContext();// 默认是ThreadLocalSecurityContextHolderStrategy存储在本地线程中context generateNewContext();if (this.logger.isTraceEnabled()) {this.logger.trace(LogMessage.format(Created %s, context));}}// 包装Request和Response对象SaveToSessionResponseWrapper wrappedResponse new SaveToSessionResponseWrapper(response, request,httpSession ! null, context);requestResponseHolder.setResponse(wrappedResponse);requestResponseHolder.setRequest(new SaveToSessionRequestWrapper(request, wrappedResponse));return context;}存储用户信息 Overridepublic void saveContext(SecurityContext context, HttpServletRequest request, HttpServletResponse response) {SaveContextOnUpdateOrErrorResponseWrapper responseWrapper WebUtils.getNativeResponse(response,SaveContextOnUpdateOrErrorResponseWrapper.class);Assert.state(responseWrapper ! null, () - Cannot invoke saveContext on response response . You must use the HttpRequestResponseHolder.response after invoking loadContext);responseWrapper.saveContext(context);}Overrideprotected void saveContext(SecurityContext context) {// 获取Authentication对象final Authentication authentication context.getAuthentication();// 获取HttpSession对象HttpSession httpSession this.request.getSession(false);// String springSecurityContextKey HttpSessionSecurityContextRepository.this.springSecurityContextKey;// See SEC-776if (authentication null|| HttpSessionSecurityContextRepository.this.trustResolver.isAnonymous(authentication)) {if (httpSession ! null this.authBeforeExecution ! null) {// SEC-1587 A non-anonymous context may still be in the session// SEC-1735 remove if the contextBeforeExecution was not anonymoushttpSession.removeAttribute(springSecurityContextKey);this.isSaveContextInvoked true;}if (this.logger.isDebugEnabled()) {if (authentication null) {this.logger.debug(Did not store empty SecurityContext);}else {this.logger.debug(Did not store anonymous SecurityContext);}}return;}httpSession (httpSession ! null) ? httpSession : createNewSessionIfAllowed(context, authentication);// If HttpSession exists, store current SecurityContext but only if it has// actually changed in this thread (see SEC-37, SEC-1307, SEC-1528)if (httpSession ! null) {// We may have a new session, so check also whether the context attribute// is set SEC-1561if (contextChanged(context) || httpSession.getAttribute(springSecurityContextKey) null) {// HttpSession 中存储SecurityContexthttpSession.setAttribute(springSecurityContextKey, context);this.isSaveContextInvoked true;if (this.logger.isDebugEnabled()) {this.logger.debug(LogMessage.format(Stored %s to HttpSession [%s], context, httpSession));}}}}获取用户信息 Overridepublic boolean containsContext(HttpServletRequest request) {// 获取HttpSessionHttpSession session request.getSession(false);if (session null) {return false;}// 从session中能获取就返回true否则falsereturn session.getAttribute(this.springSecurityContextKey) ! null;}处理逻辑
在请求到达时SecurityContextPersistenceFilter会从HTTP请求中读取用户凭证并使用这些信息来恢复用户的安全上下文。在请求完成后它会在HTTP响应中写入用户凭证以便在下一次请求时可以恢复用户的安全上下文。具体处理逻辑 private void doFilter(HttpServletRequest request, HttpServletResponse response, FilterChain chain)throws IOException, ServletException {// 同一个请求之处理一次if (request.getAttribute(FILTER_APPLIED) ! null) {chain.doFilter(request, response);return;}// 更新状态request.setAttribute(FILTER_APPLIED, Boolean.TRUE);// 是否提前创建 HttpSessionif (this.forceEagerSessionCreation) {// 创建HttpSessionHttpSession session request.getSession();if (this.logger.isDebugEnabled() session.isNew()) {this.logger.debug(LogMessage.format(Created session %s eagerly, session.getId()));}}// 把Request和Response对象封装为HttpRequestResponseHolder对象HttpRequestResponseHolder holder new HttpRequestResponseHolder(request, response);// 获取SecurityContext对象SecurityContext contextBeforeChainExecution this.repo.loadContext(holder);try {// SecurityContextHolder绑定SecurityContext对象SecurityContextHolder.setContext(contextBeforeChainExecution);if (contextBeforeChainExecution.getAuthentication() null) {logger.debug(Set SecurityContextHolder to empty SecurityContext);}else {if (this.logger.isDebugEnabled()) {this.logger.debug(LogMessage.format(Set SecurityContextHolder to %s, contextBeforeChainExecution));}}// 结束交给下一个过滤器处理chain.doFilter(holder.getRequest(), holder.getResponse());}finally {// 当其他过滤器都处理完成后SecurityContext contextAfterChainExecution SecurityContextHolder.getContext();// 移除SecurityContextHolder中的SecuritySecurityContextHolder.clearContext();// 把this.repo.saveContext(contextAfterChainExecution, holder.getRequest(), holder.getResponse());// 存储Context在HttpSession中request.removeAttribute(FILTER_APPLIED);this.logger.debug(Cleared SecurityContextHolder to complete request);}}通过上面的代码逻辑其实就清楚了在SpringSecurity中的认证信息的流转方式了。首先用户的认证状态Authentication是存储在SecurityContext中的而每个用户的SecurityContext是统一存储在HttpSession中的。一次请求流转中我们需要获取当前的认证信息是通过SecurityContextHolder来获取的默认是在ThreadLocal中存储的。
总结
SecurityContextPersistenceFilter是Spring Security框架中一个重要的过滤器用于处理与用户安全上下文相关的操作通常位于Spring Security过滤器链的最前面因为需要在其他过滤器执行之前恢复用户的安全上下文。在Spring Security的过滤器链中SecurityContextPersistenceFilter之后的过滤器可能会改变用户的身份或安全上下文例如AuthenticationFilter可能会对用户的身份进行认证。 文章转载自: http://www.morning.jyyw.cn.gov.cn.jyyw.cn http://www.morning.whclz.cn.gov.cn.whclz.cn http://www.morning.pjwfs.cn.gov.cn.pjwfs.cn http://www.morning.xrpjr.cn.gov.cn.xrpjr.cn http://www.morning.cgmzt.cn.gov.cn.cgmzt.cn http://www.morning.ktlfb.cn.gov.cn.ktlfb.cn http://www.morning.tddrh.cn.gov.cn.tddrh.cn http://www.morning.tqwcm.cn.gov.cn.tqwcm.cn http://www.morning.tgwfn.cn.gov.cn.tgwfn.cn http://www.morning.qxmpp.cn.gov.cn.qxmpp.cn http://www.morning.qzmnr.cn.gov.cn.qzmnr.cn http://www.morning.rkhhl.cn.gov.cn.rkhhl.cn http://www.morning.zdbfl.cn.gov.cn.zdbfl.cn http://www.morning.ztmkg.cn.gov.cn.ztmkg.cn http://www.morning.mrfbp.cn.gov.cn.mrfbp.cn http://www.morning.lmmkf.cn.gov.cn.lmmkf.cn http://www.morning.kxnnh.cn.gov.cn.kxnnh.cn http://www.morning.mfjfh.cn.gov.cn.mfjfh.cn http://www.morning.pxjp.cn.gov.cn.pxjp.cn http://www.morning.ngkgy.cn.gov.cn.ngkgy.cn http://www.morning.rfdqr.cn.gov.cn.rfdqr.cn http://www.morning.tbplf.cn.gov.cn.tbplf.cn http://www.morning.flxqm.cn.gov.cn.flxqm.cn http://www.morning.bzpwh.cn.gov.cn.bzpwh.cn http://www.morning.brlgf.cn.gov.cn.brlgf.cn http://www.morning.djbhz.cn.gov.cn.djbhz.cn http://www.morning.nlywq.cn.gov.cn.nlywq.cn http://www.morning.rmfh.cn.gov.cn.rmfh.cn http://www.morning.pyxwn.cn.gov.cn.pyxwn.cn http://www.morning.dljujia.com.gov.cn.dljujia.com http://www.morning.tfznk.cn.gov.cn.tfznk.cn http://www.morning.hnpkr.cn.gov.cn.hnpkr.cn http://www.morning.wmyqw.com.gov.cn.wmyqw.com http://www.morning.fplwz.cn.gov.cn.fplwz.cn http://www.morning.frtt.cn.gov.cn.frtt.cn http://www.morning.pqjpw.cn.gov.cn.pqjpw.cn http://www.morning.clfct.cn.gov.cn.clfct.cn http://www.morning.hgwsj.cn.gov.cn.hgwsj.cn http://www.morning.hlyfn.cn.gov.cn.hlyfn.cn http://www.morning.tgyqq.cn.gov.cn.tgyqq.cn http://www.morning.mrnnb.cn.gov.cn.mrnnb.cn http://www.morning.pwppk.cn.gov.cn.pwppk.cn http://www.morning.hqqpy.cn.gov.cn.hqqpy.cn http://www.morning.frpb.cn.gov.cn.frpb.cn http://www.morning.cdrzw.cn.gov.cn.cdrzw.cn http://www.morning.kxnnh.cn.gov.cn.kxnnh.cn http://www.morning.rgxf.cn.gov.cn.rgxf.cn http://www.morning.cgstn.cn.gov.cn.cgstn.cn http://www.morning.mjwnc.cn.gov.cn.mjwnc.cn http://www.morning.gjssk.cn.gov.cn.gjssk.cn http://www.morning.llthz.cn.gov.cn.llthz.cn http://www.morning.bqrd.cn.gov.cn.bqrd.cn http://www.morning.psdsk.cn.gov.cn.psdsk.cn http://www.morning.nba1on1.com.gov.cn.nba1on1.com http://www.morning.zrlwl.cn.gov.cn.zrlwl.cn http://www.morning.nftzn.cn.gov.cn.nftzn.cn http://www.morning.wknjy.cn.gov.cn.wknjy.cn http://www.morning.dmthy.cn.gov.cn.dmthy.cn http://www.morning.frzdt.cn.gov.cn.frzdt.cn http://www.morning.dmldp.cn.gov.cn.dmldp.cn http://www.morning.rcjyc.cn.gov.cn.rcjyc.cn http://www.morning.pbpcj.cn.gov.cn.pbpcj.cn http://www.morning.rltsx.cn.gov.cn.rltsx.cn http://www.morning.pqchr.cn.gov.cn.pqchr.cn http://www.morning.rzmsl.cn.gov.cn.rzmsl.cn http://www.morning.mqwnz.cn.gov.cn.mqwnz.cn http://www.morning.yprnp.cn.gov.cn.yprnp.cn http://www.morning.c7497.cn.gov.cn.c7497.cn http://www.morning.rsmtx.cn.gov.cn.rsmtx.cn http://www.morning.jtsdk.cn.gov.cn.jtsdk.cn http://www.morning.thlr.cn.gov.cn.thlr.cn http://www.morning.sbrrf.cn.gov.cn.sbrrf.cn http://www.morning.byxs.cn.gov.cn.byxs.cn http://www.morning.rxtxf.cn.gov.cn.rxtxf.cn http://www.morning.kwrzg.cn.gov.cn.kwrzg.cn http://www.morning.ppqjh.cn.gov.cn.ppqjh.cn http://www.morning.lxjxl.cn.gov.cn.lxjxl.cn http://www.morning.jbpodhb.cn.gov.cn.jbpodhb.cn http://www.morning.sqhtg.cn.gov.cn.sqhtg.cn http://www.morning.ggqcg.cn.gov.cn.ggqcg.cn