草庐IT

java - SecurityContextLogoutHandler 的 clearAuthentication 如何不是线程安全的?

coder 2024-03-06 原文

Spring 的 SecurityContextLogoutHandler 指出 clearAuthentication 标志用于:

removes the Authentication from the SecurityContext to prevent issues with concurrent requests.

SecurityContext 中删除 Authentication 可以避免什么具体问题?为什么仅仅使 session 无效(这是 SecurityContextLogoutHandler 的另一职责)还不够?

不清除 SecurityContext 是否担心 SecurityContextPersistenceFilter 可能会将当前身份验证保留到新的 session ID?仅通过新 session 有效地让用户保持登录状态?

最佳答案

What is SecurityContextLogoutHandler?

SecurityContextLogoutHandler 是实现 LogoutHandler 的处理程序。

What SecurityContextLogoutHandler does?

  1. 它通过修改 SecurityContextHolder 执行注销。
  2. 如果 isInvalidateHttpSession() 也会使 HttpSession 无效 为真且 session 不为空。
  3. 它还将从当前的身份验证中删除身份验证 SecurityContext 如果 clearAuthentication 设置为 true(默认)。

Is SecurityContextHolder thread safe?

是的,默认策略 (MODE_THREADLOCAL) 是线程安全的(只要您不尝试即时更改策略)。但是,如果您希望生成的线程继承父线程的 SecurityContext,则应设置 MODE_INHERITABLETHREADLOCAL。

此外,方面没有任何“线程逻辑”,它们与建议的方法在同一线程中执行。

归功于@ axtavt

What is authentication in Spring Security?

身份验证:该框架尝试使用提供的凭据来识别最终用户。可以针对插入 Spring Security 的第三方系统完成身份验证。

让我们考虑一个大家都熟悉的标准身份验证场景。

  1. 系统会提示用户使用用户名和密码登录。
  2. 系统(成功)验证密码是否正确 用户名。
  3. 获取该用户的上下文信息(他们的列表 角色等等)。

为用户建立安全上下文 用户继续执行某些操作,这些操作可能受到访问控制机制的保护,该机制根据当前安全上下文信息检查操作所需的权限。

前三项构成了身份验证过程,因此我们将了解这些在 Spring Security 中是如何发生的。

  1. 获取用户名和密码并组合成一个实例 UsernamePasswordAuthenticationToken 的一个实例 身份验证接口(interface),我们之前看到过)。
  2. token 被传递给 AuthenticationManager 的实例 验证。
  3. AuthenticationManager 返回一个完全填充的 Authentication 成功验证的实例。
  4. 安全上下文是通过调用建立的 SecurityContextHolder.getContext().setAuthentication(...), 通过 在返回的身份验证对象中。

SecurityContextPersistentFilter

这个名字很露骨。 SecurityContextPersistentFilter 接口(interface)的目的是将安全上下文存储在某个存储库中。 为完成此任务,过滤器将作业委托(delegate)给 SecurityContextRepository 接口(interface)。 Spring为此接口(interface)提供了默认实现:org.springframework.security.web.context.HttpSessionSecurityContextRepository .这是不言自明的。安全上下文的存储库只是当前用户的 HTTP session 。 下面是 SecurityContextPersistentFilter 的 XML 配置

<!-- Filter to store the Authentication object in the HTTP Session -->   
<bean id="securityContextPersistentFilter"
    class="org.springframework.security.web.context.SecurityContextPersistenceFilter">
    <property name="securityContextRepository" ref="securityContextRepository" />
</bean>


<bean id="securityContextRepository"
    class="org.springframework.security.web.context.HttpSessionSecurityContextRepository" />

LogoutFilter

LogoutFilter 负责注销当前用户并使安全上下文无效。使 HTTP session 无效的任务再次委托(delegate)给另一个参与者,即 SecurityContextLogoutHandler。

此处理程序被注入(inject)到 LogoutFilter 构造函数中:

<bean id="logoutFilter"
    class="org.springframework.security.web.authentication.logout.LogoutFilter">
    <constructor-arg value="/pages/Security/logout.html" />
    <constructor-arg>
        <list>
            <bean class="org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler"/>
        </list>
    </constructor-arg>
    <property name="filterProcessesUrl" value="/j_myApplication_logout"/>
</bean>

<constructor-arg value="/pages/Security/logout.html" /> - 它定义注销页面的 URL。

SecurityContextLogoutHandler 在 <bean class="org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler"/> 处作为构造函数参数注入(inject)

注销操作的 HTML URL 由位于 <property name="filterProcessesUrl" value="/j_myApplication_logout"/> 的 filterProcessesUrl 参数定义

资源链接:

  1. https://doanduyhai.wordpress.com/2012/01/22/spring-security-part-i-configuration-and-security-chain/
  2. https://doanduyhai.wordpress.com/2012/02/05/spring-security-part-ii-securitycontextpersistentfilter-logoutfilter/
  3. http://shazsterblog.blogspot.com/2014/02/spring-security-custom-filterchainproxy.html
  4. http://docs.spring.io/spring-security/site/docs/3.0.x/apidocs/org/springframework/security/web/context/SecurityContextPersistenceFilter.html

关于java - SecurityContextLogoutHandler 的 clearAuthentication 如何不是线程安全的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36802557/

有关java - SecurityContextLogoutHandler 的 clearAuthentication 如何不是线程安全的?的更多相关文章

  1. ruby - 如何使用 Nokogiri 的 xpath 和 at_xpath 方法 - 2

    我正在学习如何使用Nokogiri,根据这段代码我遇到了一些问题:require'rubygems'require'mechanize'post_agent=WWW::Mechanize.newpost_page=post_agent.get('http://www.vbulletin.org/forum/showthread.php?t=230708')puts"\nabsolutepathwithtbodygivesnil"putspost_page.parser.xpath('/html/body/div/div/div/div/div/table/tbody/tr/td/div

  2. ruby - 如何从 ruby​​ 中的字符串运行任意对象方法? - 2

    总的来说,我对ruby​​还比较陌生,我正在为我正在创建的对象编写一些rspec测试用例。许多测试用例都非常基础,我只是想确保正确填充和返回值。我想知道是否有办法使用循环结构来执行此操作。不必为我要测试的每个方法都设置一个assertEquals。例如:describeitem,"TestingtheItem"doit"willhaveanullvaluetostart"doitem=Item.new#HereIcoulddotheitem.name.shouldbe_nil#thenIcoulddoitem.category.shouldbe_nilendend但我想要一些方法来使用

  3. python - 如何使用 Ruby 或 Python 创建一系列高音调和低音调的蜂鸣声? - 2

    关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。

  4. ruby-on-rails - 如何验证 update_all 是否实际在 Rails 中更新 - 2

    给定这段代码defcreate@upgrades=User.update_all(["role=?","upgraded"],:id=>params[:upgrade])redirect_toadmin_upgrades_path,:notice=>"Successfullyupgradeduser."end我如何在该操作中实际验证它们是否已保存或未重定向到适当的页面和消息? 最佳答案 在Rails3中,update_all不返回任何有意义的信息,除了已更新的记录数(这可能取决于您的DBMS是否返回该信息)。http://ar.ru

  5. ruby-on-rails - 'compass watch' 是如何工作的/它是如何与 rails 一起使用的 - 2

    我在我的项目目录中完成了compasscreate.和compassinitrails。几个问题:我已将我的.sass文件放在public/stylesheets中。这是放置它们的正确位置吗?当我运行compasswatch时,它不会自动编译这些.sass文件。我必须手动指定文件:compasswatchpublic/stylesheets/myfile.sass等。如何让它自动运行?文件ie.css、print.css和screen.css已放在stylesheets/compiled。如何在编译后不让它们重新出现的情况下删除它们?我自己编译的.sass文件编译成compiled/t

  6. ruby - 如何将脚本文件的末尾读取为数据文件(Perl 或任何其他语言) - 2

    我正在寻找执行以下操作的正确语法(在Perl、Shell或Ruby中):#variabletoaccessthedatalinesappendedasafileEND_OF_SCRIPT_MARKERrawdatastartshereanditcontinues. 最佳答案 Perl用__DATA__做这个:#!/usr/bin/perlusestrict;usewarnings;while(){print;}__DATA__Texttoprintgoeshere 关于ruby-如何将脚

  7. ruby - 如何指定 Rack 处理程序 - 2

    Rackup通过Rack的默认处理程序成功运行任何Rack应用程序。例如:classRackAppdefcall(environment)['200',{'Content-Type'=>'text/html'},["Helloworld"]]endendrunRackApp.new但是当最后一行更改为使用Rack的内置CGI处理程序时,rackup给出“NoMethodErrorat/undefinedmethod`call'fornil:NilClass”:Rack::Handler::CGI.runRackApp.newRack的其他内置处理程序也提出了同样的反对意见。例如Rack

  8. ruby - 如何每月在 Heroku 运行一次 Scheduler 插件? - 2

    在选择我想要运行操作的频率时,唯一的选项是“每天”、“每小时”和“每10分钟”。谢谢!我想为我的Rails3.1应用程序运行调度程序。 最佳答案 这不是一个优雅的解决方案,但您可以安排它每天运行,并在实际开始工作之前检查日期是否为当月的第一天。 关于ruby-如何每月在Heroku运行一次Scheduler插件?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/8692687/

  9. ruby-on-rails - 如何从 format.xml 中删除 <hash></hash> - 2

    我有一个对象has_many应呈现为xml的子对象。这不是问题。我的问题是我创建了一个Hash包含此数据,就像解析器需要它一样。但是rails自动将整个文件包含在.........我需要摆脱type="array"和我该如何处理?我没有在文档中找到任何内容。 最佳答案 我遇到了同样的问题;这是我的XML:我在用这个:entries.to_xml将散列数据转换为XML,但这会将条目的数据包装到中所以我修改了:entries.to_xml(root:"Contacts")但这仍然将转换后的XML包装在“联系人”中,将我的XML代码修改为

  10. ruby - 如何使用文字标量样式在 YAML 中转储字符串? - 2

    我有一大串格式化数据(例如JSON),我想使用Psychinruby​​同时保留格式转储到YAML。基本上,我希望JSON使用literalstyle出现在YAML中:---json:|{"page":1,"results":["item","another"],"total_pages":0}但是,当我使用YAML.dump时,它不使用文字样式。我得到这样的东西:---json:!"{\n\"page\":1,\n\"results\":[\n\"item\",\"another\"\n],\n\"total_pages\":0\n}\n"我如何告诉Psych以想要的样式转储标量?解

随机推荐