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),然后返回需要“协商”身份验证 (2)。然后,浏览器将请求 Kerberos 服务器获取所谓的服务票证 (3)。然后,浏览器将此服务票证(证明调用者的身份)和一些其他信息发送到 Web 应用程序 (5)。在基于 Web 应用程序和 Kerberos 服务器之间的一些共享密钥验证票证后,您将获得用户名。

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

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

尽管这指的是 Microsoft Windows 2008 Server,但在 2003 甚至 2000 Server 中也应该非常相似。在 Active Directory 中,您只需创建一个普通的域用户,然后为他分配一个服务主体名称 (SPN),并使用命令行实用程序创建密钥表。以下是分步操作:

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

之后,您必须使用命令行工具“ktpass.exe”。它已包含在 Windows 2008 Server 中,在早期版本中,您需要自行安装它。只需确保您使用的版本与您的服务器版本匹配,并且区域设置也应匹配。此工具会将服务主体名称 (SPN) 分配给您之前创建的用户,并将用户密钥导出到密钥表文件。如果您的服务主体名称为“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

然后,您应该在根目录下有一个名为 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 应用程序,您可以将其用作起点。您只需配置您的服务主体名称并将生成的密钥表放置在那里。示例应用程序包含在上文提到的 下载 中。

如果您打开示例应用程序的 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 来获取角色,以及可能的一些其他用户属性。在此示例中,我们仅使用一个虚拟实现来简化测试。

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

现在启动您的服务器,并尝试进行 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 里程碑存储库添加到您的 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 问题

获取 Spring 电子邮件简报

通过 Spring 电子邮件简报保持联系

订阅

领先一步

VMware 提供培训和认证,以加速您的进步。

了解更多

获取支持

Tanzu Spring 在一个简单的订阅中提供 OpenJDK™、Spring 和 Apache Tomcat® 的支持和二进制文件。

了解更多

即将举行的活动

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

查看全部