Spring Security Kerberos/SPNEGO 扩展

工程 | Mike Wiesner | 2009 年 9 月 28 日 | ...

我们很高兴宣布 Spring Security Kerberos 扩展的第一个里程碑版本现已可供下载。该版本也可通过 Maven 里程碑仓库获取,地址是http://maven.springframework.org/milestone。借助 Spring Security Kerberos 扩展,您的用户只需打开 URL 即可通过您的 Web 应用程序进行身份验证。无需输入用户名/密码,也无需安装额外的软件。

在深入探讨 Kerberos 之前,我想先介绍一下Spring Security 扩展,这是一个新的Spring 扩展项目,致力于为核心 Spring Security 项目提供扩展模块。目前我们已经开发了两个扩展:SAML2 集成和 Kerberos/SPNEGO 集成。每个模块都有自己的发布周期,这样人们就可以在这些扩展准备就绪后立即使用它们,而无需等待下一个 Spring Security 版本。如果您对进一步的扩展有任何想法,甚至是代码,请告诉我们!

Kerberos/SPNEGO

在该模块的第一个里程碑版本中,我们为您提供了开箱即用的 Web 应用程序 Kerberos/SPNEGO 解决方案。Kerberos 是一种标准化的网络认证协议,旨在为客户端/服务器应用(例如浏览器充当客户端的 Web 应用)提供强大的认证。它也是 Windows 网络中推荐的用户认证方式,并取代了过时且相对不安全的 NTLM。此外,它在 *NIX 环境中得到广泛应用,并且适用于所有主要平台。因此,很可能您已经部署了 Kerberos,现在您也可以在自己的 Web 应用中使用它了。这意味着您的用户只需输入 URL,他就会使用其域名用户名自动进行身份验证,例如 [email protected]。然后,您可以通过 Spring Security 或甚至是 request.getRemoteUser() 获取此用户名。这是如何工作的?这里有一个简要概述:SPNEGO

浏览器向您的 Web 应用发送 GET 请求 (1),然后 Web 应用返回需要“协商”认证 (2)。接着,浏览器会向 Kerberos 服务器请求获取一个所谓的服务票据 (3)。随后,浏览器将此服务票据(证明调用者的身份)和一些额外信息发送给 Web 应用 (5)。Web 应用根据其与 Kerberos 服务器之间的共享密钥验证票据后,即可获得用户名。

为了实现这一点,每个 Web 应用都需要在 Kerberos 服务器上注册,并分配一个服务主体和一个共享密钥。对于 Web 应用,服务主体必须是“HTTP/<完全限定域名>@域”。例如,如果您的应用运行在 web.springsource.com 上,则服务主体应为“HTTP/web.[email protected]”。然后,您需要将此主体的凭据导出到 keytab 文件(共享密钥)中,并将其提供给您的应用。所有基于 Kerberos 的系统都以这种方式工作,但创建此服务主体和 keytab 的方式在不同系统之间有所差异。我将向您展示如何在 Microsoft Windows 和 MIT Kerberos 中执行此操作,但它也应该适用于其他实现。

使用 Microsoft Windows 2008 Server 创建服务主体

尽管这里指的是 Microsoft Windows 2008 Server,但它在 2003 甚至 2000 Server 中的步骤应该非常相似。在 ActiveDirectory 中,您只需创建一个普通的域用户,然后为其分配一个服务主体名称 (SPN),并使用命令行工具创建 keytab。现在一步一步来

创建一个普通用户,它将成为服务主体。用户名和密码对 Kerberos 来说没有意义,但您当然应该选择一个有用的名称,例如 http-web.springsource.com。只需确保您停用“用户下次登录时必须更改密码”选项并启用“密码永不过期”。

之后,您必须使用命令行工具“ktpass.exe”。它已包含在 Windows 2008 Server 中,在早期版本中您必须自行安装。只需确保您使用的版本与您的服务器版本以及区域设置相匹配即可。此工具将把服务主体名称 (SPN) 分配给您之前创建的用户,并将用户密钥导出到 keytab 文件。如果您的服务主体是“HTTP/web.[email protected]”,并且您的用户是 http-web.springsource.com,则您的 ktpass 命令应该如下所示


ktpass /out http-web.keytab /mapuser [email protected] /princ HTTP/[email protected]  /pass *

ktpass 会提示您输入一些密码。您应该为此选择一个安全的随机密码。如果您现在目录中有一个 http-web.keytab 文件,则一切正常。您的应用程序稍后需要此文件,因为它包含用于验证服务票据的共享密钥。

使用 MIT Kerberos 创建服务主体

在 *NIX 系统和 Mac OS X 中,MIT Kerberos 实现被广泛使用。使用 MIT Kerberos 则更简单。只需打开 kadmin 控制台并执行以下命令

kadmin:  addprinc -randkey HTTP/web.springsource.com
kadmin:  ktadd -k /http-web.keytab HTTP/web.springsource.com

然后您应该在 root 下有一个 http-web.keytab 文件。您的应用程序稍后需要此文件,因为它包含用于验证服务票据的共享密钥。

配置 Spring Security

首先,要求
  • Spring Security 3.0.0 M2
  • SUN JRE/JDK 1.6.x
  • Kerberos 环境
  • 支持 SPNEGO 的浏览器 (Firefox, IE, Safari)

为了在 Spring Security 中使用 Kerberos 模块,您只需声明一个过滤器、一个身份验证入口点和一个身份验证提供程序。我们包含了一个示例 Web 应用程序,您可以将其用作起点。您只需配置您的服务主体名称并将生成的 keytab 文件放在那里。示例应用程序包含在上面提到的下载中。

如果您打开示例应用程序中的 security.xml 文件(位于 /src/main/webapp/WEB-INF 下),您会看到一个使用新 Kerberos 模块的基本 Spring Security 配置。


<sec:http entry-point-ref="spnegoEntryPoint">
	<sec:intercept-url pattern="/secure/**" access="IS_AUTHENTICATED_FULLY" />
	<sec:custom-filter ref="spnegoAuthenticationProcessingFilter" position="BASIC_PROCESSING_FILTER" />
</sec:http>

<bean id="spnegoEntryPoint" class="org.springframework.security.extensions.kerberos.web.SpnegoEntryPoint" />

<bean id="spnegoAuthenticationProcessingFilter" class="org.springframework.security.extensions.kerberos.web.SpnegoAuthenticationProcessingFilter">
	<property name="authenticationManager" ref="authenticationManager" />
</bean>

<sec:authentication-manager alias="authenticationManager">
	<sec:authentication-provider ref="kerberosServiceAuthenticationProvider" />
</sec:authentication-manager>

<bean id="kerberosServiceAuthenticationProvider" class="org.springframework.security.extensions.kerberos.KerberosServiceAuthenticationProvider">
	<property name="ticketValidator">
		<bean class="org.springframework.security.extensions.kerberos.SunJaasKerberosTicketValidator">
			<property name="servicePrincipal" value="HTTP/web.springsource.com" />
			<property name="keyTabLocation" value="classpath:http-web.keytab" />
		</bean>
	</property>
	<property name="userDetailsService" ref="dummyUserDetailsService" />
</bean>

<!-- Just returns the User authenticated by Kerberos and gives him the ROLE_USER -->
<bean id="dummyUserDetailsService" class="org.springframework.security.extensions.kerberos.sample.DummyUserDetailsService"/>

前两个 bean (SpnegoEntryPoint 和 SpnegoAuthenticationProcessingFilter) 负责握手过程,然后 KerberosServiceAuthenticationProvider 最终验证服务票据。目前,我们只支持 SUN 的 JRE/JDK 中包含的 Kerberos/SPNEGO 实现。由于您只能从 Kerberos 中获取用户名,因此您还需要一个 UserDetailsService 来获取角色以及可能的一些其他用户属性。在此示例中,我们仅使用一个虚拟实现以便于测试。

如您所见,我们已经填写了服务主体名称和 keytab 位置。根据您的需要更改这些值,并确保之前生成的 keytab 可在此位置找到。

现在启动您的服务器并尝试进行 SPNEGO 认证。您应该在浏览器中看到您的完整域名用户名。在您的代码中,您可以使用常规的 Spring Security 类,甚至使用标准的 Java Servlet 调用 request.getRemoteUser() 来检索用户名。如果它不起作用(可能您看到一个空白页),请检查以下事项

  • 检查日志文件
  • 确保您在 URL 中使用了完全限定域名(不是 IP 地址,也不是短名称)。
  • 如果您使用 Internet Explorer:开启“Windows 集成认证”,并确保该域名(在我们的示例中为 web.springsource.com)已列入 IE 的本地 Intranet 网站区域。
  • 如果您使用 Firefox:请查看此处
  • 如果您使用 Windows 客户端:客户端和服务器必须在不同的机器上,否则 Windows 将使用 NTLM 而不是 Kerberos。
  • 检查所有相关机器上的时间是否同步。
  • 如果您使用 Microsoft AD,您可以在此处找到更多帮助:http://msdn.microsoft.com/en-us/library/ms995329.aspx
    • 除此之外,搭建一个合适的 Kerberos 环境可能很复杂,在使用 Spring Security Kerberos 扩展之前正确配置它非常重要。我们在咨询中遇到的大多数问题都与 Kerberos 环境有关,而不是应用程序本身。

      如果您想在自己的 Maven 项目中使用 Spring Security Kerberos 扩展,则必须将 Spring Milestone Repository 添加到您的 pom.xml 中。它应该看起来像这样

      
      <repositories>
      	<repository>
      		<id>spring-milestone</id>
      		<name>Spring Portfolio Milestone Repository</name>
      		<url>http://maven.springframework.org/milestone </url>
      	</repository>
      </repositories>
      

      当然还有依赖项

      
      <dependency>
      	<groupId>org.springframework.security.extensions</groupId>
      	<artifactId>spring-security-kerberos-core</artifactId>
      	<version>1.0.0.M1</version>
      </dependency>
      

      还有一些工作要做,例如为 Java 客户端而不仅仅是服务器提供 Kerberos 支持,但我们希望您能尝试此里程碑版本并提供一些反馈。社区论坛是提问或讨论新功能的最佳场所。或者,如果您发现问题,可以提交一个 Jira Issue

获取 Spring 快讯

订阅 Spring 快讯以保持联系

订阅

领先一步

VMware 提供培训和认证,助力您的职业发展。

了解更多

获取支持

Tanzu Spring 提供 OpenJDK™、Spring 和 Apache Tomcat® 的支持和二进制文件,只需一份简单订阅即可获得。

了解更多

即将举行的活动

查看 Spring 社区的所有即将举行的活动。

查看全部