- 浏览: 1193500 次
- 性别:
- 来自: 杭州
文章分类
最新评论
-
insistboy:
写的太棒了,受不了
WebLogic11g-创建域(Domain) -
goldyeah:
厉害了 困扰我大半个月的问题解决了 谢谢博主
WebLogic11g-单双向SSL配置(以Springside3为例) -
zy315351965:
404伤不起
开源流程引擎Snaker -
nannan408:
双向的时候谷歌提示“不接受您的登录证书,或者您可能没有提供登录 ...
WebLogic11g-单双向SSL配置(以Springside3为例) -
一颗赛艇:
不成功啊。启动有问题 <Security> < ...
WebLogic11g-单双向SSL配置(以Springside3为例)
讲解完http标签的解析过程,authentication-manager标签解析部分就很容易理解了
authentication-manager标签在spring的配置文件中的定义一般如下
authentication-manager标签的解析类是:
org.springframework.security.config.authentication.AuthenticationManagerBeanDefinitionParser
具体解析方法parse的代码为
通过上面的代码片段,能够知道authentication-manager标签解析的步骤是
1.构造ProviderManager的BeanDefinition
2.循环authentication-manager的子标签,构造provider的BeanDefinition,并添加到providers集合中
3.将第2步的providers设置为ProviderManager的providers属性
4.构造异常事件发布类DefaultAuthenticationEventPublisher的BeanDefinition,并设置为ProviderManager的属性authenticationEventPublisher
5.通过registerBeanComponent方法完成bean的注册任务
authentication-provider标签的解析类为
org.springframework.security.config.authentication.AuthenticationProviderBeanDefinitionParser
如果学习过acegi的配置,应该知道,acegi有这么一段配置
实际上authentication-manager标签所要达到的目标就是构造上面的bean。其中anonymousAuthenticationProvider是在http解析过程添加的。
其实可以完全像acegi那样自定义每个bean。
上面的标签如果用bean来定义,则可以完全由下面的xml来替代。
需要注意的是anonymousAuthenticationProvider的bean中,需要增加key属性。如果采用authentication-manager标签的方式,key虽然没有定义,在增加AnonymousAuthenticationFilter过滤器中,是通过java.security.SecureRandom.nextLong()来生成的。
显而易见,如果采用bean的方式来定义,非常复杂,而且需要了解底层的组装过程才行,不过能够提高更大的扩展性。采用authentication-manager标签的方式,很简洁,只需要提供UserDetailsService即可。
authentication-manager标签在spring的配置文件中的定义一般如下
<authentication-manager alias="authenticationManager"> <authentication-provider user-service-ref="userDetailsManager"/> </authentication-manager>
authentication-manager标签的解析类是:
org.springframework.security.config.authentication.AuthenticationManagerBeanDefinitionParser
具体解析方法parse的代码为
public BeanDefinition parse(Element element, ParserContext pc) { Assert.state(!pc.getRegistry().containsBeanDefinition(BeanIds.AUTHENTICATION_MANAGER), "AuthenticationManager has already been registered!"); pc.pushContainingComponent(new CompositeComponentDefinition(element.getTagName(), pc.extractSource(element))); //构造ProviderManager的BeanDefinition BeanDefinitionBuilder providerManagerBldr = BeanDefinitionBuilder.rootBeanDefinition(ProviderManager.class); //获取alias属性 String alias = element.getAttribute(ATT_ALIAS); //检查session-controller-ref属性,提示通过标签<concurrent-session-control>取代 checkForDeprecatedSessionControllerRef(element, pc); List<BeanMetadataElement> providers = new ManagedList<BeanMetadataElement>(); NamespaceHandlerResolver resolver = pc.getReaderContext().getNamespaceHandlerResolver(); //获取authentication-manager的子节点 NodeList children = element.getChildNodes(); //循环节点,一般子节点主要是authentication-provider或者 //ldap-authentication-provider for (int i = 0; i < children.getLength(); i++) { Node node = children.item(i); if (node instanceof Element) { Element providerElt = (Element)node; //判断子标签是否有ref属性,如果有,则直接将ref属性 //引用的bean id添加到providers集合中 if (StringUtils.hasText(providerElt.getAttribute(ATT_REF))) { providers.add(new RuntimeBeanReference(providerElt.getAttribute(ATT_REF))); } else { //如果没有ref属性,则通过子标签的解析类完成标签解析 //如子标签:authentication-provider,解析过程在后面 BeanDefinition provider = resolver.resolve(providerElt.getNamespaceURI()).parse(providerElt, pc); Assert.notNull(provider, "Parser for " + providerElt.getNodeName() + " returned a null bean definition"); String id = pc.getReaderContext().generateBeanName(provider); //注册provider的BeanDefinition pc.registerBeanComponent(new BeanComponentDefinition(provider, id)); //添加注册过的bean到provider集合中 providers.add(new RuntimeBeanReference(id)); } } } if (providers.isEmpty()) { providers.add(new RootBeanDefinition(NullAuthenticationProvider.class)); } providerManagerBldr.addPropertyValue("providers", providers); //添加默认的事件发布类 BeanDefinition publisher = new RootBeanDefinition(DefaultAuthenticationEventPublisher.class); String id = pc.getReaderContext().generateBeanName(publisher); pc.registerBeanComponent(new BeanComponentDefinition(publisher, id)); //将事件发布类的bean注入到ProviderManager的 //authenticationEventPublisher属性中 providerManagerBldr.addPropertyReference("authenticationEventPublisher", id); //注册ProviderManager的bean pc.registerBeanComponent( new BeanComponentDefinition(providerManagerBldr.getBeanDefinition(), BeanIds.AUTHENTICATION_MANAGER)); if (StringUtils.hasText(alias)) { pc.getRegistry().registerAlias(BeanIds.AUTHENTICATION_MANAGER, alias); pc.getReaderContext().fireAliasRegistered(BeanIds.AUTHENTICATION_MANAGER, alias, pc.extractSource(element)); } pc.popAndRegisterContainingComponent(); return null; }
通过上面的代码片段,能够知道authentication-manager标签解析的步骤是
1.构造ProviderManager的BeanDefinition
2.循环authentication-manager的子标签,构造provider的BeanDefinition,并添加到providers集合中
3.将第2步的providers设置为ProviderManager的providers属性
4.构造异常事件发布类DefaultAuthenticationEventPublisher的BeanDefinition,并设置为ProviderManager的属性authenticationEventPublisher
5.通过registerBeanComponent方法完成bean的注册任务
authentication-provider标签的解析类为
org.springframework.security.config.authentication.AuthenticationProviderBeanDefinitionParser
public BeanDefinition parse(Element element, ParserContext parserContext) { //首先构造DaoAuthenticationProvider的BeanDefinition RootBeanDefinition authProvider = new RootBeanDefinition(DaoAuthenticationProvider.class); authProvider.setSource(parserContext.extractSource(element)); //获取password-encoder子标签 Element passwordEncoderElt = DomUtils.getChildElementByTagName(element, Elements.PASSWORD_ENCODER); if (passwordEncoderElt != null) { //如果有password-encoder子标签,把解析任务交给 //PasswordEncoderParser完成 PasswordEncoderParser pep = new PasswordEncoderParser(passwordEncoderElt, parserContext); authProvider.getPropertyValues().addPropertyValue("passwordEncoder", pep.getPasswordEncoder()); //如果有salt-source标签,将值注入到saltSource属性中 if (pep.getSaltSource() != null) { authProvider.getPropertyValues().addPropertyValue("saltSource", pep.getSaltSource()); } } //下面获取子标签user-service、jdbc-user-service、ldap-user-service Element userServiceElt = DomUtils.getChildElementByTagName(element, Elements.USER_SERVICE); Element jdbcUserServiceElt = DomUtils.getChildElementByTagName(element, Elements.JDBC_USER_SERVICE); Element ldapUserServiceElt = DomUtils.getChildElementByTagName(element, Elements.LDAP_USER_SERVICE); String ref = element.getAttribute(ATT_USER_DETAILS_REF); if (StringUtils.hasText(ref)) { if (userServiceElt != null || jdbcUserServiceElt != null || ldapUserServiceElt != null) { parserContext.getReaderContext().error("The " + ATT_USER_DETAILS_REF + " attribute cannot be used in combination with child" + "elements '" + Elements.USER_SERVICE + "', '" + Elements.JDBC_USER_SERVICE + "' or '" + Elements.LDAP_USER_SERVICE + "'", element); } } else { // Use the child elements to create the UserDetailsService AbstractUserDetailsServiceBeanDefinitionParser parser = null; Element elt = null; //下面的if语句,主要是根据子标签的不同,选择子标签对应的解析器处理 if (userServiceElt != null) { elt = userServiceElt; parser = new UserServiceBeanDefinitionParser(); } else if (jdbcUserServiceElt != null) { elt = jdbcUserServiceElt; parser = new JdbcUserServiceBeanDefinitionParser(); } else if (ldapUserServiceElt != null) { elt = ldapUserServiceElt; parser = new LdapUserServiceBeanDefinitionParser(); } else { parserContext.getReaderContext().error("A user-service is required", element); } parser.parse(elt, parserContext); ref = parser.getId(); String cacheRef = elt.getAttribute(AbstractUserDetailsServiceBeanDefinitionParser.CACHE_REF); if (StringUtils.hasText(cacheRef)) { authProvider.getPropertyValues().addPropertyValue("userCache", new RuntimeBeanReference(cacheRef)); } } //将解析后的bean id注入到userDetailsService属性中 authProvider.getPropertyValues().addPropertyValue("userDetailsService", new RuntimeBeanReference(ref)); return authProvider; }
如果学习过acegi的配置,应该知道,acegi有这么一段配置
<bean id="authenticationManager" class="org.acegisecurity.providers.ProviderManager"> <property name="providers"> <list> <ref local="daoAuthenticationProvider"/> <ref local="anonymousAuthenticationProvider"/> </list> </property> </bean>
实际上authentication-manager标签所要达到的目标就是构造上面的bean。其中anonymousAuthenticationProvider是在http解析过程添加的。
其实可以完全像acegi那样自定义每个bean。
<authentication-manager alias="authenticationManager"> <authentication-provider user-service-ref="userDetailsManager"/> </authentication-manager>
上面的标签如果用bean来定义,则可以完全由下面的xml来替代。
<bean id="org.springframework.security.authenticationManager" class="org.springframework.security.authentication.ProviderManager"> <property name="authenticationEventPublisher" ref="defaultAuthenticationEventPublisher"></property> <property name="providers"> <list> <ref local="daoAuthenticationProvider"/> <ref local="anonymousAuthenticationProvider"/> </list> </property> </bean> <bean id="defaultAuthenticationEventPublisher" class="org.springframework.security.authentication.DefaultAuthenticationEventPublisher"></bean> <bean id="anonymousAuthenticationProvider" class="org.springframework.security.authentication.AnonymousAuthenticationProvider"> <property name="key"><value>work</value></property> </bean> <bean id="daoAuthenticationProvider" class="org.springframework.security.authentication.dao.DaoAuthenticationProvider"> <property name="userDetailsService" ref="userDetailsManager"></property> </bean>
需要注意的是anonymousAuthenticationProvider的bean中,需要增加key属性。如果采用authentication-manager标签的方式,key虽然没有定义,在增加AnonymousAuthenticationFilter过滤器中,是通过java.security.SecureRandom.nextLong()来生成的。
显而易见,如果采用bean的方式来定义,非常复杂,而且需要了解底层的组装过程才行,不过能够提高更大的扩展性。采用authentication-manager标签的方式,很简洁,只需要提供UserDetailsService即可。
发表评论
-
Spring Security3源码分析-电子书下载
2012-07-30 14:34 8545提供电子书下载链接。 -
Spring Security3源码分析-CAS支持
2012-05-13 21:03 25776Spring Security3对CAS的支持主要在这个spr ... -
Spring Security3源码分析-SSL支持
2012-05-10 12:48 11074Sping Security3对于SSL的支持仅仅表现在对需要 ... -
Spring Security3源码分析-认证授权分析
2012-05-09 21:59 6362前面分析了FilterChainProxy执行过程,也对常用的 ... -
Spring Security3源码分析-Filter链排序分析
2012-05-09 14:39 15302通过前面Spring Security提供的各种Filter的 ... -
Spring Security3源码分析-RequestCacheAwareFilter分析
2012-05-09 12:55 4881RequestCacheAwareFilter过滤器对应的类路 ... -
Spring Security3源码分析-ExceptionTranslationFilter分析
2012-05-09 10:03 7802ExceptionTranslationFilter过滤器对应 ... -
Spring Security3源码分析-SessionManagementFilter分析-下
2012-05-08 21:03 6336很多spring security3资料在 ... -
Spring Security3源码分析-SessionManagementFilter分析-上
2012-05-08 17:26 10919SessionManagementFilter过滤 ... -
Spring Security3源码分析-AnonymousAuthenticationFilter分析
2012-05-08 10:32 5195AnonymousAuthenticationFilter ... -
Spring Security3源码分析-BasicAuthenticationFilter分析
2012-05-08 09:24 9603BasicAuthenticationFilter过滤器对应的 ... -
Spring Security3源码分析-FilterSecurityInterceptor分析
2012-05-07 17:31 15285FilterSecurityInterceptor过滤器对应的 ... -
Spring Security3源码分析-SecurityContextHolderAwareRequestFilter分析
2012-05-07 10:34 6819SecurityContextHolderAwareReque ... -
Spring Security3源码分析-RememberMeAuthenticationFilter分析
2012-05-06 22:33 5946RememberMeAuthenticationFilter过 ... -
Spring Security3源码分析-UsernamePasswordAuthenticationFilter分析
2012-05-06 11:54 24860UsernamePasswordAuthenticationF ... -
Spring Security3源码分析-LogoutFilter分析
2012-05-06 10:18 10296LogoutFilter过滤器对应的类路径为 org.spri ... -
Spring Security3源码分析-SecurityContextPersistenceFilter分析
2012-05-06 08:22 8723通过观察Filter的名字,就能大概猜出来这个过滤器的作用,是 ... -
Spring Security3源码分析-FilterChainProxy执行过程分析
2012-05-06 07:48 4242通过FilterChainProxy的初始化、自定义标签的分析 ... -
Spring Security3源码分析-http标签解析
2012-05-05 15:29 8439在FilterChainProxy初始化的 ... -
Spring Security3源码分析-FilterChainProxy初始化
2012-05-04 16:57 20048很久没有更新博客了,最近对Spring Security做了比 ...
相关推荐
This module provides a new dialect called org.thymeleaf.extras.springsecurity3.dialect.SpringSecurityDialect or org.thymeleaf.extras.springsecurity4.dialect.SpringSecurityDialect (depending on the ...
You will then learn about a variety of authentication mechanisms and how to integrate them easily with the Spring MVC application. You will also understand how to achieve authorization in a Spring ...
Spring Security多身份验证展示柜基于Spring Boot的示例应用程序,展示了用于多个身份验证流程的案例Java配置-Siteminder SSO和基于表单的登录。入门/运行应用程序克隆存储库,使用maven将其打包为jar,然后从目标...
具有Spring Security的Spring Boot服务器架构您可以使用下图概述我们的Spring Boot Server: 有关更多详细信息,请访问: 全栈认证全栈CRUD应用在一个地方同时运行后端和前端:相依性–如果要使用PostgreSQL: ...
springsecurity角色和权限
单点登录(Single Sign On , 简称 SSO )是目前比较流行的服务于企业业务整合的解决方案之一, SSO 使得在多个应用系统中,用户只...本文介绍了 CAS 的原理、协议、以及配合Spring-Security在 Tomcat 中的配置和使用。
spring-boot-jwt-authentication登录
Spring-Security-authentication-against-MongoDB-Using-Morphia 这是一个演示示例,它使用 Morphia API 演示了针对 mongoDB 的 Spring 身份验证 此示例使用带有 Gradle 插件的 STS IDE 开发。 要运行该应用程序,...
<authentication-manager> 元素 B.2.1.1. <authentication-provider>元素 B.2.1.2. 使用<authentication-provider> 来引用一个AuthenticationProvider Bean B.3. 方法安全 B.3.1. <global-method-security>...
3、Spring Security 2.x Overview 4、Dive Into Spring Security Authentication Authorization 5、Development Experiences & Demo 6、Q & A 张明星 5年以上保险、电信大中型项目开发经验,对JavaEE有较深入理解...
Spring Security 的前身是 Acegi Security ,是 Spring 项目组中用来提供安全认证服务的框架。 Spring Security 为基于J2EE企业应用软件提供了全面安全服务。特别是使用领先的J2EE解决方案-Spring框架开发的企业...
3. Spring Security 4.2的新特性 27 3.1 Web改进 27 3.2配置改进 28 3.3杂项 28 4.样品和指南(从这里开始) 28 5. Java配置 29 5.1 Hello Web安全Java配置 29 5.1.1 AbstractSecurityWebApplicationInitializer 31 ...
jwt-react-authentication-源码.rar
Laravel开发-two-factor-authentication Laravel的双因素认证(2FA)
官方版本,亲测可用
官方版本,亲测可用
springsecurity是一个功能强大且高度可定制的身份验证和访问控制框架。springsecurity是一个...最核心的就是 Basic Authentication Filter 用来认证用户的身份,一个在spring security中一种过滤器处理一种认证方式。
Spring Security是什么? 历史 发布版本号 Getting Spring Security Spring Security 4.1新特性 Java 配置提升 Web应用程序安全性提升 授权改进 密码模块的改进 测试的改进 一般的改进 样品和指南 (Start Here) Java ...
<authentication-manager>元素 B.2.1.1. <authentication-provider>元素 B.2.1.2. 使用 <authentication-provider> 来引用一个 AuthenticationProvider Bean B.3. 方法安全 B.3.1. <global-method-security>...
WG-Authentication-Gateway_12_3_1,WatchGuard 防火墙sso插件