Spring Security 内置的InMemoryUserDetailsManager配置过程

本文详细介绍了Spring Security内置的InMemoryUserDetailsManager的配置过程,它用于从配置文件加载用户账户信息。UserServiceBeanDefinitionParser解析配置,通过getBeanClassName方法指定InMemoryUserDetailsManager,并在AbstractUserDetailsServiceBeanDefinitionParser的parse方法中创建实例。当存在缓存引用时,会注册一个使用CachingUserDetailsService的缓存版用户服务。

InMemoryUserDetailsManager是Spring Security 内置的实现UserDetailsManager 接口的默认配置实现。它主要负责从配置文件中加载用户的账户信息。观察Spring Security源代码可清晰发现其配置过程。

 

  1. UserServiceBeanDefinitionParser类解析配置文件<user-service>元素。代码第6行:
    private void loadParsers() {
            // Parsers
            parsers.put(Elements.LDAP_PROVIDER, new LdapProviderBeanDefinitionParser());
            parsers.put(Elements.LDAP_SERVER, new LdapServerBeanDefinitionParser());
            parsers.put(Elements.LDAP_USER_SERVICE, new LdapUserServiceBeanDefinitionParser());
            parsers.put(Elements.USER_SERVICE, new UserServiceBeanDefinitionParser());
            parsers.put(Elements.JDBC_USER_SERVICE, new JdbcUserServiceBeanDefinitionParser());
            parsers.put(Elements.AUTHENTICATION_PROVIDER, new AuthenticationProviderBeanDefinitionParser());
            parsers.put(Elements.GLOBAL_METHOD_SECURITY, new GlobalMethodSecurityBeanDefinitionParser());
            parsers.put(Elements.AUTHENTICATION_MANAGER, new AuthenticationManagerBeanDefinitionParser());
            parsers.put(Elements.METHOD_SECURITY_METADATA_SOURCE, new MethodSecurityMetadataSourceBeanDefinitionParser());
    
            // Only load the web-namespace parsers if the web classes are available
            if(ClassUtils.isPresent(FILTER_CHAIN_PROXY_CLASSNAME, getClass().getClassLoader())) {
                parsers.put(Elements.DEBUG, new DebugBeanDefinitionParser());
                parsers.put(Elements.HTTP, new HttpSecurityBeanDefinitionParser());
                parsers.put(Elements.HTTP_FIREWALL, new HttpFirewallBeanDefinitionParser());
                parsers.put(Elements.FILTER_INVOCATION_DEFINITION_SOURCE, new FilterInvocationSecurityMetadataSourceParser());
                parsers.put(Elements.FILTER_SECURITY_METADATA_SOURCE, new FilterInvocationSecurityMetadataSourceParser());
                parsers.put(Elements.FILTER_CHAIN, new FilterChainBeanDefinitionParser());
                filterChainMapBDD = new FilterChainMapBeanDefinitionDecorator();
            }
        }
     
  2. UserServiceBeanDefinitionParser类有一个方法:getBeanClassName:
    protected String getBeanClassName(Element element) {
            return InMemoryUserDetailsManager.class.getName();
        }
     
  3. UserServiceBeanDefinitionParser父类AbstractUserDetailsServiceBeanDefinitionParser的parse方法内部创建InMemoryUserDetailsManager,代码第2行:
    public BeanDefinition parse(Element element, ParserContext parserContext) {
            BeanDefinitionBuilder builder = BeanDefinitionBuilder.rootBeanDefinition(getBeanClassName(element));
    
            doParse(element, parserContext, builder);
    
            RootBeanDefinition userService = (RootBeanDefinition) builder.getBeanDefinition();
            final String beanId = resolveId(element, userService, parserContext);
    
            parserContext.registerBeanComponent(new BeanComponentDefinition(userService, beanId));
    
            String cacheRef = element.getAttribute(CACHE_REF);
    
            // Register a caching version of the user service if there's a cache-ref
            if (StringUtils.hasText(cacheRef)) {
                BeanDefinitionBuilder cachingUSBuilder = BeanDefinitionBuilder.rootBeanDefinition(CachingUserDetailsService.class);
                cachingUSBuilder.addConstructorArgReference(beanId);
    
                cachingUSBuilder.addPropertyValue("userCache", new RuntimeBeanReference(cacheRef));
                BeanDefinition cachingUserService = cachingUSBuilder.getBeanDefinition();
                parserContext.registerBeanComponent(new BeanComponentDefinition(cachingUserService, beanId + CACHING_SUFFIX));
            }
    
            return null;
        }
     
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值