关于spring security自定义sessionRegistry

最近调了一下spring security的集群session共享,用到了自定义的SessionRegistry,却发现怎么也不工作,翻了翻stackoverfllow,也没找到靠谱的办法,最后自己debug,找到了问题所在

本文基于 Spring3.1.5,Spring security 2.0.4

最开始配置如下:


1

2

3

4

5

6

7

8

9

10

11

<beans:bean id="sessionRegistry"

     class="com.shop.core.security.support.SessionRegistryImpl" scope="singleton">

   <beans:property name="cacheManager" ref="cacheManager" />

</beans:bean>

<bean:http auto-config="false" entry-point-ref="loginUrlEntryPoint">

...

<bean:concurrent-session-control max-sessions="200000"

   exception-if-maximum-exceeded="false" expired-url="/outline.htm"

   session-registry-alias="sessionRegistry"  />

...

</bean:http>

debug发现自定义的SessionRegistryImpl类也有载入,但是最终系统调用的仍然是原来的

org.springframework.security.concurrent.SessionRegistryImpl

通过阅读源代码发现了其中原因,解释见注释:


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

public class ConcurrentSessionsBeanDefinitionParser implements BeanDefinitionParser {

    static final String ATT_EXPIRY_URL = "expired-url";

    static final String ATT_MAX_SESSIONS = "max-sessions";

    static final String ATT_EXCEPTION_IF_MAX_EXCEEDED = "exception-if-maximum-exceeded";

    static final String ATT_SESSION_REGISTRY_ALIAS = "session-registry-alias";

    static final String ATT_SESSION_REGISTRY_REF = "session-registry-ref";

   

    public BeanDefinition parse(Element element, ParserContext parserContext) {

       CompositeComponentDefinition compositeDef =

         new CompositeComponentDefinition(element.getTagName(), parserContext.extractSource(element));

      parserContext.pushContainingComponent(compositeDef);

       

       BeanDefinitionRegistry beanRegistry = parserContext.getRegistry();

//这里通过session-registry-ref 去获取自定义的sessionregistry,

        String sessionRegistryId = element.getAttribute(ATT_SESSION_REGISTRY_REF);

        

        if (!StringUtils.hasText(sessionRegistryId)) {         

            RootBeanDefinition sessionRegistry = new RootBeanDefinition(SessionRegistryImpl.class);        

            beanRegistry.registerBeanDefinition(BeanIds.SESSION_REGISTRY, sessionRegistry);

            parserContext.registerComponent(new BeanComponentDefinition(sessionRegistry, BeanIds.SESSION_REGISTRY));

            sessionRegistryId = BeanIds.SESSION_REGISTRY;

        else {

        //注册默认ID

           // Register the default ID as an alias so that things like session fixation filter can access it

           beanRegistry.registerAlias(sessionRegistryId, BeanIds.SESSION_REGISTRY);

        }

        String registryAlias = element.getAttribute(ATT_SESSION_REGISTRY_ALIAS);

        if (StringUtils.hasText(registryAlias)) {

           beanRegistry.registerAlias(sessionRegistryId, registryAlias);

        }      

        BeanDefinitionBuilder filterBuilder =

                BeanDefinitionBuilder.rootBeanDefinition(ConcurrentSessionFilter.class);

        filterBuilder.addPropertyValue("sessionRegistry"new RuntimeBeanReference(sessionRegistryId));

也即是说sessionRegistry在做初始化的时候,spring security用了beanRegistry去管理了自身默认的bean的实现,java培训时学到的东西。如果你要使用自定义的,就需要给出相应的配置以取代默认,在BeanIds抽象类里面定义了默认的实现别名,如果获取不到就去获取默认。


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

public abstract class BeanIds {

    /** External alias for FilterChainProxy bean, for use in web.xml files */

    public static final String SPRING_SECURITY_FILTER_CHAIN = "springSecurityFilterChain";  

    /** Package protected as end users shouldn‘t really be using this BFPP directly */

   static final String INTERCEPT_METHODS_BEAN_FACTORY_POST_PROCESSOR = "_interceptMethodsBeanfactoryPP";

    static final String CONTEXT_SOURCE_SETTING_POST_PROCESSOR = "_contextSettingPostProcessor";

    static final String ENTRY_POINT_INJECTION_POST_PROCESSOR = "_entryPointInjectionBeanPostProcessor";

    static final String USER_DETAILS_SERVICE_INJECTION_POST_PROCESSOR = "_userServiceInjectionPostProcessor";

    static final String SESSION_REGISTRY_INJECTION_POST_PROCESSOR = "_sessionRegistryInjectionPostProcessor";    

    static final String FILTER_CHAIN_POST_PROCESSOR = "_filterChainProxyPostProcessor";

    static final String FILTER_LIST = "_filterChainList";

    public static final String JDBC_USER_DETAILS_MANAGER = "_jdbcUserDetailsManager";

   public static final String USER_DETAILS_SERVICE = "_userDetailsService";

   public static final String ANONYMOUS_PROCESSING_FILTER = "_anonymousProcessingFilter";

   public static final String ANONYMOUS_AUTHENTICATION_PROVIDER = "_anonymousAuthenticationProvider";

   public static final String BASIC_AUTHENTICATION_FILTER = "_basicAuthenticationFilter";

   public static final String BASIC_AUTHENTICATION_ENTRY_POINT = "_basicAuthenticationEntryPoint";

   public static final String SESSION_REGISTRY = "_sessionRegistry";

   public static final String CONCURRENT_SESSION_FILTER = "_concurrentSessionFilter";

   所以我的配置里面只需要加上session-registry-ref就好了。。

   <beans:bean id="sessionRegistry"

     class="com.shop.core.security.support.SessionRegistryImpl" scope="singleton">

   <beans:property name="cacheManager" ref="cacheManager" />

</beans:bean>

<bean:http auto-config="false" entry-point-ref="loginUrlEntryPoint">

...

<bean:concurrent-session-control max-sessions="200000"

   exception-if-maximum-exceeded="false" expired-url="/outline.htm"

   session-registry-alias="sessionRegistry"  session-registry-ref="sessionRegistry"/>

...

</bean:http>

时间: 2024-08-30 12:44:54

关于spring security自定义sessionRegistry的相关文章

关于spring security自定义sessionRegistry不工作的原因简析

最近调了一下spring security的集群session共享,用到了自定义的SessionRegistry,却发现怎么也不工作,翻了翻stackoverfllow,也没找到靠谱的办法,最后自己debug,找到了问题所在 本文基于 Spring3.1.5,Spring security 2.0.4 最开始配置如下: <beans:bean id="sessionRegistry"      class="com.shop.core.security.support.

spring security自定义指南

序 本文主要研究一下几种自定义spring security的方式 主要方式 自定义UserDetailsService 自定义passwordEncoder 自定义filter 自定义AuthenticationProvider 自定义AccessDecisionManager 自定义securityMetadataSource 自定义access访问控制 自定义authenticationEntryPoint 自定义多个WebSecurityConfigurerAdapter 自定义User

Spring Security 自定义登录认证(二)

一.前言 本篇文章将讲述Spring Security自定义登录认证校验用户名.密码,自定义密码加密方式,以及在前后端分离的情况下认证失败或成功处理返回json格式数据 温馨小提示:Spring Security中有默认的密码加密方式以及登录用户认证校验,但小编这里选择自定义是为了方便以后业务扩展,比如系统默认带一个超级管理员,当认证时识别到是超级管理员账号登录访问时给它赋予最高权限,可以访问系统所有api接口,或在登录认证成功后存入token以便用户访问系统其它接口时通过token认证用户权限

02 spring security 自定义用户认证流程

1. 自定义登录页面 (1)首先在static目录下面创建login.html       注意: springboot项目默认可以访问resources/resources, resources/staic, resources/public目录下面的静态文件 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>登录页

Spring Security自定义用户认证

具体代码地址 https://gitee.com/chuzhuyong/HandleSafer 自定义用户认证 通过自定义WebSecurityConfigurerAdapter类型的Bean组件,并重写configure(Authentication ManagerBuilder auth)方法, 可以实现自定义用户认证. 一.内存身份认证   In-Memory Authentication(内存身份认证)是最简单的身份认证方式,主要用于Security安全认证体验和测试 1.自定义WebS

Spring Security 自定义登录验证与自定义回调地址

1 配置文件 security-ns.xml <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:security="http://www

spring security自定义拒绝访问页面

如果试图访问一个没有访问权限的页面,那么页面会出现403 访问错误. 如果我们希望自定义访问拒绝页面,只需要随便创建一个jsp页面,让后将这个页面的位置放到配置文件中. 下面创建一个accessDenied.jsp <%@ page contentType="text/html;charset=UTF-8"%> <html> <head> <meta http-equiv="Content-Type" content=&qu

Spring Security登陆

本文参考或摘录自:http://haohaoxuexi.iteye.com/blog/2154714 在上一篇中使用Spring Security做了一些安全控制,如Spring Security 自动生成登陆页面登陆以后便能正常使用系统.本文介绍Spring Security 自定义登陆页面以及相关的一些处理. Spring Security 之form-login. 1.使用form-login 自定义登陆页 2.使用form-login做登陆引导处理,即登陆成功后定向到其他页面 3.使用f

255.Spring Boot+Spring Security:使用md5加密

说明 (1)JDK版本:1.8 (2)Spring Boot 2.0.6 (3)Spring Security 5.0.9 (4)Spring Data JPA 2.0.11.RELEASE (5)hibernate5.2.17.Final (6)MySQLDriver 5.1.47 (7)MySQL 8.0.12 需求缘起 很多时候,我们自己已经有现成的一套系统在运行了,这时候要接入spring security的话,那么难免会碰到一个问题:就是自己设计的密码加密方式和spring secur