InMemoryUserDetailsManager是Spring Security 内置的实现UserDetailsManager 接口的默认配置实现。它主要负责从配置文件中加载用户的账户信息。观察Spring Security源代码可清晰发现其配置过程。
- 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(); } }
- UserServiceBeanDefinitionParser类有一个方法:getBeanClassName:
protected String getBeanClassName(Element element) { return InMemoryUserDetailsManager.class.getName(); }
- 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; }