在 WebSphere Application Server Community Edition 中配置 Kerberos 验证

WebSphere® Application Server Community Edition 目前不支持 Kerberos 验证。本文介绍如何利用 IBM® Java™ Platform 提供的 Kerberos,实现在 WebSphere Application Server Community Edition 中执行 Kerberos 验证。

Ashish Jain, 软件工程师, WSO2 Inc

作者照片Ashish Jain 是位于印度班加罗尔 IBM 印度软件实验室的一名软件工程师,他的工作是担任 IBM WebSphere Application Server Community Edition 的 Level 3 技术支持。Ashish 拥有印度 NITK Surathkal 大学的计算机科学的工程学士学位,于 2005 年作为 ELTP 加入 IBM。


developerWorks 投稿作者

Vamsavardhana Reddy Chillakuru, 顾问软件工程师, WSO2 Inc

作者照片Vamsavardhana Reddy Chillakuru 又名 Vamsi,是位于印度班加罗尔的 IBM 印度软件实验室的一名顾问软件工程师。他是 Apache Geronimo 和 Apache Tuscany 的参与者,也是 IBM WebSphere Application Server Community Edition Level 3 Support Team 的成员。他分别于 1994 年和 1996 年获得了位于印度加尔各答的印度统计研究所 (Indian Statistical Institute) 的统计学学士学位(荣誉)和统计学硕士学位。



2010 年 1 月 28 日

简介

IBM WebSphere Application Server Community Edition V2.1.1.2 (以下简称为 Community Edition)是一个基于 Apache Geronimo 2.1.4 的免费 Java Platform, Enterprise Edition 5.0 (Java EE 5) 认证应用服务器。Community Edition 使用 Java Authentication and Authorization Service (JAAS) 登录模块在 Web 应用程序中进行用户验证,使用 Java Authorization Contract for Containers (JACC) 进行授权

Kerberos 是由麻省理工学院开发的验证协议。Kerberos 协议允许在不安全的计算机网络上通信的计算机节点以一种安全的方式互相验证。Kerberos 协议的最新版本为 Version 5。

Community Edition 并不提供 Kerberos 协议实现。在本文中,您将利用 IBM Java Platform 提供的 Kerberos 协议实现在 Community Edition 中验证用户并对用户授权。为实现本文的目的,我们使用一个 Microsoft® Active Directory 服务器(以下简称为 Active Directory)作为一个用户资源库。本文需要 WebSphere Application Server Community Edition V2.1.1.2 或更高版本。


Kerberos:它是如何工作的?

Kerberos 使用对称密匙密码系统,需要一个称为 Key Distribution Center (KDC) 的可信第三方,KDC 包含一个 Authentication Server (AS) 和一个 Ticket Granting Server (TGS)。KDC 维护一个秘密密匙数据库。网络上的每个实体(用户或服务)都与 KDC 共享一个秘密密匙,这个秘密密匙只有 KDC 和实体自身知晓。这样,通过这个秘密密匙就可以对实体进行身份验证。Kerberos 使用票据(ticket),称为 “Kerberos 票据”,该票据拥有时间戳且存在时间很短。因此,实体必须保持时间同步。

实体使用一个共享秘密(通常是密码)对 Authentication Server 进行验证,并接收一个 Ticket Granting Ticket (TGT)。然后它联系 Ticket Granting Server,使用 TGT 验证其身份并请求一个服务。TGS 验证该实体是否有权使用服务并发送一个 Service Ticket (ST)。该实体然后联系 Service Server (SS),使用 ST 证明自己有权利用服务,然后实际使用服务。实体能够重复使用 TGT 获取额外的 ST 以使用 SS,无需再次使用 AS 验证自己。Kerberos 协议经过特殊设计,无需在网络上传播共享秘密(如密码)就可以进行验证。使用 Kerberos 验证时,用户通常使用一个输入设备(如键盘)输入他们的凭证,而服务使用一个 Keytab 文件存储用户凭证,并使用它们对 KDC 进行验证。


Kerberos 和 Community Edition

Community Edition 提供 Kerberos 协议的实现。IBM Java Platform 通过 com.ibm.security.auth.module.Krb5LoginModule 类提供 Kerberos 协议的一个实现。为了利用 Java Platform 提供的 Kerberos 实现,我们创建一个包装 Krb5LoginModule 的 LoginModule 实现,并将所有 LoginModule API 调用委托给 Krb5LoginModule。KerberosLoginModule 的代码如清单 1 所示。

清单 1. KerberosLoginModule.java
package org.apache.geronimo.security.realm.providers;

import java.security.Principal;
import java.util.HashMap;
import java.util.Map;

import javax.security.auth.Subject;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.login.LoginException;
import javax.security.auth.spi.LoginModule;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

public class KerberosLoginModule implements LoginModule {

    private static Log log = LogFactory.getLog(KerberosLoginModule.class);
    private Subject subject;
    private LoginModule krb5LoginModule;
    private Subject krb5Subject;
    private Principal addOnPrincipal;

    public void initialize(Subject subject, CallbackHandler callbackHandler,
 Map sharedState, Map options) {
        this.subject = subject;
        String krb5LoginModuleClass = (String) options.get("krb5LoginModuleClass");
        try {
            krb5LoginModule = (LoginModule)Class.forName(krb5LoginModuleClass)
.newInstance();
        } catch (Exception e) {
            log.error("Initialization failed", e);
            throw new IllegalArgumentException("Unable to configure 
kerberos login module: " + e.getMessage(),e);
        }
        
        Map options1 = new HashMap();
        for(Object key : options.keySet()) {
            String key1 = (String) key;
            if(key1.startsWith("krb_")) {
                options1.put(key1.substring(4), options.get(key1));
            }
        }
        
        krb5Subject = new Subject();
krb5LoginModule.initialize(krb5Subject, callbackHandler, sharedState,
options1);
String addOnPrincipalClass = (String) options.get("addOnPrincipalClass");
String addOnPrincipalName = (String) options.get("addOnPrincipalName");
if(addOnPrincipalClass != null && !addOnPrincipalClass.equals("")) {
   try {
   addOnPrincipal = (Principal) Class.forName(addOnPrincipalClass).getConstructor
    (String.class).newInstance(addOnPrincipalName);
            } catch (Exception e) {
             log.error("Initialization failed", e);
             throw new IllegalArgumentException("Unable to configure kerberos login 
              module: " + e.getMessage(), e);
            }
        }
    }

    public boolean login() throws LoginException {
        return krb5LoginModule.login();
    }

    public boolean commit() throws LoginException {
        boolean result = krb5LoginModule.commit();
        if(result) {
         if(addOnPrincipal != null) subject.getPrincipals().add(addOnPrincipal);

subject.getPrincipals().addAll(krb5Subject.getPrincipals());
       subject.getPublicCredentials().addAll(krb5Subject.getPublicCredentials());
       subject.getPrivateCredentials().addAll(krb5Subject.getPrivateCredentials());
        }
        return result;
    }

public boolean abort() throws LoginException {
        return krb5LoginModule.abort();
    }

public boolean logout() throws LoginException {
    if(!subject.isReadOnly()) {
    // Remove principals and credentials added by this LoginModule
    if(addOnPrincipal != null) subject.getPrincipals().remove(addOnPrincipal);
subject.getPrincipals().removeAll(krb5Subject.getPrincipals());
 
   subject.getPublicCredentials().removeAll(krb5Subject.getPublicCredentials());
   subject.getPrivateCredentials().removeAll(krb5Subject.getPrivateCredentials());
        }
        return krb5LoginModule.logout();
    }
}

KerberosLoginModule 拥有以下 LoginModule 选项:

  • krb5LoginModuleClass:指定由 Java Platform 提供的 Kerberos 协议实现的完全限定名。这个类必须实现 javax.security.auth.spi.LoginModule 接口。由于我们将使用 IBM Java Platform 提供的 Krb5LoginModule,这个值为 com.ibm.security.auth.module.Krb5LoginModule
  • addOnPrincipalClass:指定登录成功后添加到主题(subject)的主体(principal)的类的完全限定名。除了使用 krb5LoginModuleClass 登录导致的其他主体外,这个主体也将被添加到主题。如果不需要添加更多主体,则不要使用这个选项。
  • addOnPrincipalName:指定要添加到主题的主体的名称。这个选项只在指定了 addOnPrincipalClass 的情况下使用。
  • krb_*:传递到 krb5LoginModuleClass 的 initialize() 方法的任意选项必须使用一个 “krb_” 前缀。在选项传递到 initialize() 方法之前,前缀 “krb_” 将从选项名中删除。例如 krb_debug=true 将以 debug=true 形式传递到 initialize() 方法。

KerberosLoginModule.initialize() 方法为使用 krb5LoginModuleClass 选项配置的类创建一个实例,它只使用名称以前缀 “krb_” 开头的那些选项初始化该实例,但初始化时将删除前缀。它还创建一个通过 addOnPrincipalClass 和 addOnPrincipalName 选项 配置的附加(add-on)主体。成功验证后,KerberosLoginModule.commit() 方法将 krb5LoginModuleClass 登录导致的所有 Principals、Public Credentials 和 Private Credentials 以及附加 Principal 添加到 Subject。KerberosLoginModule 类用于创建使用 Kerberos 协议在 Community Edition 中执行验证的安全域。


在 Microsoft Active Directory 中建立用户

安装和配置 Microsoft Active Directory 服务器超出了本文的范围。根据我们的配置,我们已经在端口 88 启动了 Key Distribution Centre (KDC)。执行以下步骤以向 Active Directory 服务器添加新用户。

  1. 启动 Active Directory Users and Computers 并选择 Users,如图 1 所示。
    图 1. Active Directory 用户和计算机
    Active Directory 用户和计算机
  2. 右键单击 Users 并选择 New > User,如图 2 所示。
    Figure 2. 创建新用户
    创建新用户
  3. 在对话框中,填充 First Name、Last Name 和 User logon name 并单击 Next,如图 3 所示。
    图 3. 创建新用户 —— 用户细节
    创建新用户 —— 用户细节
  4. 输入用户密码并单击 Next,如图 4 所示。
    图 4. 创建新用户 —— 密码
    创建新用户 —— 密码
  5. 单击 Finish 完成新用户添加,如图 5 所示。
    图 5. 创建新用户 —— 新用户已添加
    创建新用户 —— 新用户已添加

可以看到,新创建的用户在 “Users” 下列示。


建立客户机

这个步骤要求将 Kerberos 配置文件复制到预定义的位置。对于 Windows 客户机,这个文件名为 “krb5.ini”,位于 “C:/winnt/” 目录中。对于 Linux 客户机,这个文件名为 “krb5.conf”,位于 “/etc” 目录中。我们使用的 Kerberos 配置文件如清单 2 所示。

清单 2. Kerberos 配置文件 —— krb5.ini
[libdefaults]
default_realm = AUSTIN.IBM.COM
default_tkt_enctypes = rc4-hmac,des-cbc-md5,des-cbc-crc
default_tgs_enctypes = rc4-hmac,des-cbc-md5,des-cbc-crc

[realms]
AUSTIN.IBM.COM = {
 		kdc = ad1ldap.austin.ibm.com:88
}

[domain_realm]
austin.ibm.com = AUSTIN.IBM.COM
.austin.ibm.com = AUSTIN.IBM.COM

下面让我们看看这个配置文件中的每个部分和条目。

第一个部分是 [libdefaults],它描述 Kerberos V5 库使用的默认值。这个部分中的其他字段介绍如下:

  • default_realm:这是将用于客户机和主机之间的通信的默认域。如果您使用一个主体名 “ashish”,AUSTIN.IBM.COM 将默认附加到主体名之后,这样,最终的主体为 ashish@AUSTIN.IBM.COM。
  • default_tgs_enctypes:这个字段指定 KDC 返回的会话密匙加密。当 Microsoft Active Directory 作为 KDC 使用时,确保在这个字段中指定 rc4-hmac。
  • default_tkt_enctypes:这个字段指定客户机将请求的会话密匙加密类型的列表。

第二个部分是 [realms],它描述域和 KDC 服务器映射的细节。在清单 2 中,AUSTIN.IBM.COM 已经被映射到 ad1ldap.austin.ibm.com:88。这里,ad1ldap.austin.ibm.com 是 hostName,88 是正在运行 KDC 服务器的端口号。

第三个部分是 [domain_realm],它描述从子域和域名到 Kerberos 域名的映射细节。如果一个主机具有完全限定域名,则这个部分能够确定该主机所处的域。


将自定义 Kerberos 登录模块 JAR 添加到资源库

Community Edition 的当前版本不包含 KerberosLoginModule 实现。本文提供一个包含 KerberosLoginModule 类(如清单 1 所示)的 自定义登录模块 JAR,以帮助您在 Community Edition 中创建一个 Kerberos 安全域。这个 JAR 需要添加到 Community Edition 资源库。执行以下步骤将这个登录模块 JAR 添加到 Community Edition 资源库:

  1. 启动 Community Edition,在您的浏览器中打开 http://localhost:8080/console/
  2. 输入用户名 system 和密码 manager。单击 Login,这将在管理控制台中打开 Welcome 页面,如图 6 所示。
    图 6. 管理控制台 —— Welcome 页面
    管理控制台 —— Welcome 页面
  3. 单击 Console Navigation 下的 Repository 启动 Repository portlet(如图 7 所示)。
    图 7. Repository portlet
    Repository portlet
  4. 浏览到自定义登录模块 JAR 的下载位置。如图 7 所示,命名字段并单击 Install。这将把登录模块 JAR 安装到 Community Edition 资源库中。

创建一个 Kerberos 域

本小节将介绍使用 Community Edition Administrative Console 创建一个 Kerberos 域的步骤:

  1. 在 Security 下的 Console Navigation 中单击 Security Realms 链接,如图 8 所示。
    图 8. 启动 Security Realms portlet
    启动 Security Realms portlet
  2. 在 Security Realms portlet 中, 单击 Add new security realm,如图 9 所示。
    图 9. 启动新安全域的页面
    启动新安全域的页面
  3. 在下一个页面中,将域名设置为 kerberos-realm,选择 Other 作为域类型,然后单击 Next,如图 10 所示。
    图 10. 创建新的安全域
    创建新的安全域
  4. 如图 11 所示填充表单。从下拉列表框中选择登录模块 JAR,这是此前添加到资源库中的那个 JAR。将 Login Module Class 命名为 org.apache.geronimo.security.realm.providers.KerberosLoginModule。添加如清单 3 所示的配置选项。
    清单 3. 创建安全域时的配置选项
    addOnPrincipalName=admin
    addOnPrincipalClass=org.apache.geronimo.security.realm.providers.
    GeronimoGroupPrincipal
    krb_debug=true
    krb5LoginModuleClass= com.ibm.security.auth.module.Krb5LoginModule
    图 11. 创建新的安全域 —— 配置
    创建新的安全域 —— 配置
  5. 完成后,浏览到页面底部。单击 Show Plan 显示 Kerberos 域计划,如图 12 所示。
    图 12. 显示创建的安全域计划
    显示创建的安全域计划
  6. 在下一个屏幕上,您将看到已创建的计划显示在一个文本框中,如图 13 所示。您也可以复制该计划以备将来参考。单击 Deploy 将安全域部署到 Community Edition。
    图 13. 部署安全域计划
    部署安全域计划
    如果部署成功,您将看到 “kerberos-realm” 列示在 Security Realms 页面中,如图 14 所示。
    图 14. 成功部署 Kerberos 域
    成功部署 Kerberos 域

部署并测试样例应用程序

为测试 Kerberos 域,本文提供了一个 样例应用程序。执行以下步骤部署并测试这个样例应用程序:

  1. 在 Applications 下的 Console Navigation 中单击 Deploy New,如图 15 所示。
    图 15. 启动 deploy new portlet
    启动 deploy new portlet
  2. 浏览到下载样例应用程序的位置,选择 SimpleWebApp-Subject.war 作为 Archive,选择 SimpleWebApp-Subject-plan.xml 作为 Plan,如图 16 所示。
    图 16. 安装应用程序
    安装应用程序
  3. 单击 Install 部署样例应用程序。
  4. 完成后,启动 URL http://localhost:8080/kerberos-realm-demo/admin/admin.jsp。这将显示一个屏幕以提供登录凭证(如图 17 所示)。
    图 17. 简单 Web 应用程序 —— 登录屏幕
    简单 Web 应用程序 —— 登录屏幕
  5. 输入此前创建的 Microsoft Active Directory 用户名和密码并单击 Login
  6. 成功验证后,您将看到一个欢迎页面,该页面表明主体 ashishjain@AUSTIN.IBM.COM 已添加到 admin 组。该页面还列示了生成的 Kerberos 票据,如图 18 所示。
    图 18. 成功验证后的欢迎页面和其他工件
    成功验证后的欢迎页面和其他工件

    注意,除了 KerberosPrincipal 外,Subject 还使用 addOnPrincipal 选项在域中配置了 GeronimoGroupPrincipal。

  7. 现在尝试使用一个错误密码进行登录,您将看到一条登录失败消息,如图 19 所示。
    图 19. 登录失败果
    登录失败

结束语

本文展示了如何通过创建一个 KerberosLoginModule 包装器在 Community Edition 中验证用户,以利用 IBM Java Platform 提供的 Kerberos 协议实现。本文还通过一个样例应用程序展示如何使用 Kerberos 验证列示在 Microsoft Active Directory 服务器中的用户。


下载

描述名字大小
代码样例application_files.zip10 KB

参考资料

学习

获得产品和技术

讨论

条评论

developerWorks: 登录

标有星(*)号的字段是必填字段。


需要一个 IBM ID?
忘记 IBM ID?


忘记密码?
更改您的密码

单击提交则表示您同意developerWorks 的条款和条件。 查看条款和条件

 


在您首次登录 developerWorks 时,会为您创建一份个人概要。您的个人概要中的信息(您的姓名、国家/地区,以及公司名称)是公开显示的,而且会随着您发布的任何内容一起显示,除非您选择隐藏您的公司名称。您可以随时更新您的 IBM 帐户。

所有提交的信息确保安全。

选择您的昵称



当您初次登录到 developerWorks 时,将会为您创建一份概要信息,您需要指定一个昵称。您的昵称将和您在 developerWorks 发布的内容显示在一起。

昵称长度在 3 至 31 个字符之间。 您的昵称在 developerWorks 社区中必须是唯一的,并且出于隐私保护的原因,不能是您的电子邮件地址。

标有星(*)号的字段是必填字段。

(昵称长度在 3 至 31 个字符之间)

单击提交则表示您同意developerWorks 的条款和条件。 查看条款和条件.

 


所有提交的信息确保安全。


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=10
Zone=WebSphere, Open source
ArticleID=465207
ArticleTitle=在 WebSphere Application Server Community Edition 中配置 Kerberos 验证
publish-date=01282010