• spring security session


    原文: https://www.baeldung.com/spring-security-session

    1. Overview
    这里将讲一下 how spring security allows us to control our HTTP sessions
    这种控制的范围从session timeout到enabling concurrent session及其它高级security configs.

    2. when is the session created?
    我们可以精确控制session什么时候被建立,及spring security怎样和它交互:

    always - a session will always be created if one doesn't already exist
    ifRequired - a session will be created only if required (default)
    never - the framework will never create a session ifself but it will use one if it already exists
    stateless - no session will be created or used by spring security

    <http create-session="ifRequired"> ... </http>
    java config
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.sessionManagement()
              .sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED)
    }

    如果使用stateless, 将会跳过spring security filter chain - 主要session相关部分:
       HttpSessionSecurityContextRepository, SessionManagementFilter, RequestCacheFilter

    these more strict control mechanisms have the direct implication(隐含) that COOKIES ARE NOT USED and
    so EACH AND EVERY REQUEST NEEDS TO BE RE-AUTHENTICATED.
    主要用于REST APIs

    3. Under The Hood
    执行Authentication process前, spring security将运行一个filter - 它负责在requests之间存储Security Context:  
    SecurityCotnextPersistenceFilter.
    context将根据一个策略(strategy)进行存储 - HttpSessionSecurityContextRepository(默认) - 这将使用Http Session作为存储
    对于stateless, 这个strategy被替换成另一个 - NullSecurityContextRepository.

    4. Concurrent Session Control
    当一个已经认证过的用户再次试着去authenticate, the application能以几种方式之一处理那个事件。
    或者invalidate the active session of user,然后authenticate the user again with a new session,
    或者允许两个sessions同时存在

    1.允许同时存在的第一步 (web.xml)
    <listener>
        <listener-class>org.springframework.security.web.session.HttpSessionEventPublisher</listener-class>
    </listener>

    or:

    @Bean
    public HttpSessionEventPublisher httpSessionEventPublisher() {
        return new HttpSessionEventPublisher();
    }

    这确保当session is destroyed, spring security session registry能被通知到

    第二步, 为了允许同时存在:
    <http ...>
        <session-management>
            <concurrency-control max-sessions="2" />
        </session-management>
    </http>

    or, via java configuration
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.sessionManagement().maxmumSessions(2);
    }

    5. Session Timeout
    session 超时后,如果用户发送了一个with EXPIRED SESSION ID的请求,这些请求将被redirected到一个URL,
    xml配置的URL:
    <session-management>
        <concurrency-control expired-url="/sessionExpired.html" .../>
    </session-management>

    类似,如果session无效(invalid), 重定向的url:
    <session-management invalid-session-url="/invalidSession.html">
      ...
    </session-management>


    相应的java config
    http.sessionManagement()
          .expiredUrl("/sessionExpired.html")
          .invalidSessionUrl("/invalidSession.html");

    6. Prevent using URL paramenters for Session Tracking
    <http> 添加disable-url-rewriting="true" 禁止 url rewrite
    web.xml
    <session-config>
       <tracking-mode>COOKIE</tracking-mode>
    </session-config>

    代码方式:
    servletContext.setSessionTrackingModes(EnumSet.of(SessionTrackingMode.COOKIE));
    这选择在哪存放JSESSIONID, in the cookie or in a URL parameter.

    7. Session Fixation Proection with Spring Security
    会话固定:
    防御:spring security在用户登录后,重新生成一个session id

    配置当用户再次authenticate,发生什么
    <session-management session-fixation-protection="mirgateSession"> ...

    java config
    http.sessionManagement()
          .sessionFixation().migrateSession()

    上面是spring security的默认配置,old session的属性会被复制过来
    其它配置:
      none: 原来的session不会invalidated
      newSession: 新建会话,不使用old session里的任何属性

    8. Working with the session
    session scope的bean定义: 使用@Scope annotation

    8.1 Session Scoped Beans
    @Component
    @Scope("session"
    public class Foo { .. }

    xml:
    <bean id="foo" scope="session"/>

    然后,the bean can simply be injected into another bean.
    @Autowired
    private foo Foo;

    And spring will bind the new bean to the lifecycle of the HTTP session

    8.2 Injecting the Raw Session into a Controller
    the raw HTTP Session can alse be injected directly into a Controller method.
    @RequestMapping(...)
    public void fooMethod(HttpSession session) {
        session.addAttribute(Constants.FOO, new Foo());
        ...
        Foo foo = (Foo) session.getAttribute(Constants.FOO);
    }

    8.3 Obtaining the Raw Session
    the current HTTP Session can also be obtained programmatically via the RAW Servlet API:
    ServletRequestAttributes attr = (ServletRequestAttributes)RequestContextHolder.currentRequestAttributes();
    HttpSession session = attr.getRequest().getSession(true); // true = allow create

    9. Conclusion

       ...
        OVER

    自己加点:(from spring session chapter 5)

    1. spring session透明集成HttpSession, 好处:
     .支持集群的sessions.
     .Restful APIs: spring session allows providing session IDs in headers to work with Restful APIs.
    2.  和spring security集成
      1. remember me
           ...
      2. spring security concurrent session control
         这个支持集群会话
        要自定义一个Spring security's SessionRegistry接口的实现.
       
    @Configuration
    public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
       @Autowired
       private FindByIndexNameSessionRepository<Session> sessionRepository;

       @Bean
       SpringSessionBackedSessionRegistry sessionRegistry() {
          return new SpringSessionBackedSessionRegistry<>(this.sessionRepository);
       }

       @Override
       protected void configure(HttpSecurity http) throws Exception {
          http
               // other config goes here ...
               .sessionManagement().maximumSessions(2)
               .sessionRegistry(sessionRegistry());
       }

    xml:
    <security:http>
      <security:session-management>
         <security:concurrency-control max-sessions="2" sesssion-registry-ref="sessionRepostory"/>
      </security:session-management>
    </security:http>

    <bean id="sessionRegistry" class="org.springframework.session.security.SpringSessionBackedSessionRegistry">
        <constructor-arg ref="sessionRepository"/>
    </bean>
       

  • 相关阅读:
    c程序设计语言_习题1-16_自己编写getline()函数,接收整行字符串,并完整输出
    c程序设计语言_习题1-13_统计输入中单词的长度,并且根据不同长度出现的次数绘制相应的直方图
    c程序设计语言_习题1-11_学习单元测试,自己生成测试输入文件
    c程序设计语言_习题1-9_将输入流复制到输出流,并将多个空格过滤成一个空格
    c语言时间库函数#include<time.h>
    c语言输入与输出库函数#include<stdio.h>
    c语言诊断_断言库函数#include<assert.h>
    c语言实用功能库函数#include<stdlib.h>
    Remove Duplicates from Sorted List
    Merge Sorted Array
  • 原文地址:https://www.cnblogs.com/bear129/p/9615842.html
Copyright © 2020-2023  润新知