首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 软件管理 > 软件架构设计 >

《Spring Security3》第六章第二一部分翻译(自定义AuthenticationProvider)(转载)

2012-06-26 
《Spring Security3》第六章第二部分翻译(自定义AuthenticationProvider)(转载)实现自定义的AuthenticationP

《Spring Security3》第六章第二部分翻译(自定义AuthenticationProvider)(转载)
实现自定义的AuthenticationProvider

在很多场景下,你的应用需要跳出SpringSecurity功能的边界,可能会需要实现自己的AuthenticationProvider。回忆在第二章中AuthenticationProvider的角色,在整个认证过程中,它接受安全实体请求提供的凭证(即Authentication对象或authentication token)并校验其正确性和合法性。

通过AuthenticationProvider实现一个简单的单点登录

通常,应用允许以用户或客户端方式登录。但是,有一种场景也很常见,尤其是在广泛使用的应用中,即允许系统中的不同用户以多种方式登录。

假设我们的系统与一个简单的“单点登录”提供者进行集成,用户名和密码分别在HTTP头中的j_username 和j_password发送。除此以外,j_signature头信息包含了用户名和密码的随意编码算法形成的字符串,以辅助安全请求。

【不要使用这个例子作为真实单点登录的解决方案。这个例子很牵强,只是为了说明实现一个完全自定义AuthenticationProvider的步骤。真正的SSO解决方案显然会更安全并涉及到几次的握手以建立可信任的凭证。Spring Security支持几种SSO解决方案,包括中心认证服务(CAS)和SiteMinder,我们将会在第十章:使用中心认证服务实现单点登录中介绍。实际上,Spring Security提供了一个类似的过滤器用来进行SiteMinder请求头的认证,即o.s.s.web.authentication.preauth.RequestHeaderAuthenticationFilter,也是这种类型功能的一个好例子。】

对于admin用户的登录,我们的算法期望在请求头中包含如下的数据:

一般来讲,AuthenticationProvider将会寻找特定的AuthenticationToken,而后者会在过滤器链中位置比较靠前的servlet filter里面进行填充赋值(明确会在AuthenticationManager访问检查执行之前),如下图描述:


《Spring Security3》第六章第二一部分翻译(自定义AuthenticationProvider)(转载)

?

在这种方式中,AuthenticationToken的提供者与其消费者AuthenticationProvider有一点脱离关系了。所以,在实现自定义AuthenticationProvider时,通常还需要实现一个自定义的servlet过滤器,其作用是提供特定的AuthenticationToken。

自定义认证token

我们实现自定义的方法会尽可能的使用SpringSecurity的基本功能。基于此,我们会扩展并增强基本类如UsernamePasswordAuthenticationToken,并添加一个新的域来存储我们已编码的签名字符串。最终的类com.packtpub.springsecurity.security.SignedUsernamePasswordAuthenticationToken,如下:

?

    ?? ? ? ??现在,让我们看一下代码:

    ?

      ?????????? 可以看到,这个比较简单的过滤器查找三个已命名的请求头,正如我们已经规划的那样(如果需要的话,可以通过bean属性进行配置),并监听默认的URL ?/j_spring_security_filter。正如其它的SpringSecurity过滤器那样,这是一个虚拟的URL并被我们的过滤器的基类AbstractAuthenticationProcessingFilter所识别,基于此这个过滤器采取行动尝试创建Authenticationtoken并认证用户的请求。

      在本例中,我们尽可能将错误检查最小化(译者注:即参数的合法性与完整性的检查)。可能在实际的应用中,会校验是否所有头信息都提供了以及在发现用户提供信息不正确的时候要抛出异常或对用户进行重定向。

      一个细小的配置变化是需要将我们的过滤器插入到过滤器链中:

      ?

        现在,我们写一个AuthenticationProvider的实现类,即com.packtpub.springsecurity.security.SignedUsernamePasswordAuthenticationProvider,负责校验我们自定义Authenticationtoken的签名。

        ?

          因为到目前为止,我们还没有了解其它的AuthenticationProvider,我们可以假设以下的需求,即使用标准的用户名和密码基于form的认证以及前面实现的自定义简单SSO认证。当配置了多个AuthenticationProvider时,每个AuthenticationProvider都会检查过滤器提供给它的AuthenticationToken,仅当这个token类型它支持时才会处理这个token。以这种方式,你的应用同时支持不同的认证方式并不会有什么坏处。

          连接多个AuthenticationProvider实际上很简单。只需要在我们的dogstore-security.xml配置文件中声明另一个authentication-provider引用。

          ?

            ????????? 与我们安全配置文件中引用的其它Spring bean一样,signedRequestAuthenticationProvider引用就是我们的AuthenticationProvider,它将在dogstore-base.xml中与其它的Springbean一起进行配置。

            ?


              ?将所有的头信息标示为Enabled,访问这个URL:http://localhost:8080/JBCPPets/j_spring_security_filter,会发现我们能够自动登录系统。你可能也会发现我们给予form的登录还能继续可用,这是因为保留了这两个AuthenticationProvider实现以及过滤器链中对应的过滤器。

              如果你能时刻记住它们的角色,当你在开发应用特定的AuthenticationProvider时,会在实现和调试过程中少很多的迷惑。

热点排行