开发定制 JASPI 认证提供者

可以通过创建用于实现 JSR 196: Java™ Authentication Service Provider Interface for Containers 规范中说明的必需接口的类来开发定制 Java Authentication SPI for Containers (JASPI) 认证提供者。

开始之前

查看 JSR 196: Java Authentication Service Provider Interface for Containers 规范中有关 JASPI 认证提供者和模块的特定接口实现需求。

关于此任务

WebSphere® Application Server 支持使用符合 Java Authentication SPI for Containers (JASPI) V1.1 中所指定 Servlet 容器概要文件的第三方认证提供程序。

Servlet 容器概要文件定义了一些接口,在应用程序处理 Web 请求之前和之后,安全性运行时环境与 WebSphere Application Server 中的 Web 容器协作使用这些接口来调用认证模块。仅当在安全性配置中启用了 JASPI,并且所配置的 JASPI 提供者已经与用于处理所接收到的 Web 请求的 Web 模块相关联时,才执行使用 JASPI 模块进行认证。

要开发定制认证提供者,请创建用于实现 JSR 196: Java Authentication Service Provider Interface for Containers 规范中说明的必需接口的类。提供者可以使用一个或多个认证模块来进行认证。模块可以使用回调来执行认证,它们也可以将必需的用户身份信息手动添加至客户机主体集。根据提供者的作用域不同,可以将实现类存储在应用程序服务器上的各种位置。

过程

  1. 创建用于实现 javax.security.auth.message.config.AuthConfigProvider 接口的类。
    AuthConfigProvider 实现类必须定义一个具有两个自变量的公用构造函数以及 getServerAuthConfig 公用方法:
    import java.util.Map;
    import javax.security.auth.callback.CallbackHandler;
    import javax.security.auth.message.AuthException;
    import javax.security.auth.message.config.AuthConfigFactory;
    import javax.security.auth.message.config.AuthConfigProvider;
    import javax.security.auth.message.config.ServerAuthConfig;
    
    public class SampleAuthConfigProvider implements AuthConfigProvider {
    
            public SampleAuthConfigProvider(Map<String, String> properties, AuthConfigFactory factory) {
                    ...
            }
            public ServerAuthConfig getServerAuthConfig(String layer, String appContext, CallbackHandler handler)
                    throws AuthException {
                    ...
            }
    }

    当请求要由应用程序的 Web 模块处理时,WebSphere Application Server 会使用 AuthConfigProvider 实现类的实例。getServerAuthConfig 方法用来获得 ServerAuthConfig 实例。认证模块会使用方法调用中的 CallbackHandler 自变量。

  2. 创建用于实现 javax.security.auth.message.config.ServerAuthConfig 接口的类。
    ServerAuthConfig 实现类必须定义 getAuthContextID 和 getAuthContext 公用方法:
    import java.util.Map;
    import javax.security.auth.Subject;
    import javax.security.auth.message.AuthException;
    import javax.security.auth.message.MessageInfo;
    import javax.security.auth.message.config.ServerAuthConfig;
    import javax.security.auth.message.config.ServerAuthContext;
    
    public class SampleServerAuthConfig implements ServerAuthConfig {
    
            public String getAuthContextID(MessageInfo messageInfo) throws IllegalArgumentException {
                    ...
            }
            public ServerAuthContext getAuthContext(String authContextID, Subject serviceSubject, Map properties) 
                    throws AuthException {
                    ...
            }
    }

    ServerAuthConfig 实现类中的 getAuthContextID 和 getAuthContext 方法用来获得 ServerAuthContext 实例。

  3. 创建用于实现 javax.security.auth.message.config.ServerAuthContext 接口的类。
    ServerAuthContext 实现类必须定义 validateRequest 和 secureResponse 公用方法:
    import javax.security.auth.Subject;
    import javax.security.auth.message.AuthException;
    import javax.security.auth.message.AuthStatus;
    import javax.security.auth.message.MessageInfo;
    import javax.security.auth.message.config.ServerAuthContext;
    
    public class SampleServerAuthContext implements ServerAuthContext {
    
            public AuthStatus validateRequest(MessageInfo messageInfo, Subject clientSubject, Subject serviceSubject) 
                    throws AuthException {
                    ...
            }
            public AuthStatus secureResponse(MessageInfo messageInfo, Subject serviceSubject) 
                    throws AuthException {
                    ...
            }
    }

    ServerAuthContext 实现类中的 validateRequest 方法用来调用将认证所接收到的 Web 请求消息的模块。如果认证成功,那么 Web 容器将分派目标 Web 模块在应用程序中处理的所接收到的 Web 请求消息。如果认证不成功,那么请求会被拒绝并提供适当的响应状态。

  4. 创建用于实现 javax.security.auth.message.module.ServerAuthModule 接口的类。
    ServerAuthModule 实现类必须定义 initialize、validateRequest 和 secureResponse 公用方法:
    import javax.security.auth.Subject;
    import javax.security.auth.callback.CallbackHandler;
    import javax.security.auth.message.AuthException;
    import javax.security.auth.message.AuthStatus;
    import javax.security.auth.message.MessageInfo;
    import javax.security.auth.message.MessagePolicy;
    import javax.security.auth.message.module.ServerAuthModule;
    
    public class SampleAuthModule implements ServerAuthModule {
    
            public void initialize(MessagePolicy requestPolicy, MessagePolicy responsePolicy, CallbackHandler handler, Map options) 
                    throws AuthException {
                    ...
            }
    
            public AuthStatus validateRequest(MessageInfo messageInfo, Subject clientSubject, Subject serviceSubject)
                    throws AuthException {
                    ...
            }
    
            public AuthStatus secureResponse(MessageInfo messageInfo, Subject serviceSubject) 
                    throws AuthException {
                    ...
            }
    }

    ServerAuthContext 实现类调用 ServerAuthModule 实现类中的 initialize 方法来初始化认证模块,以及使此模块与 ServerAuthContext 实例相关联。

    此类中的 validateRequest 和 secureResponse 方法分别用来认证所接收到的 javax.security.auth.message.MessageInfo 中包含的 javax.servlet.http.HttpServletRequest 和 javax.servlet.http.HttpServletResponse。 这些方法可以使用 initialize 方法中接收到的 CallbackHandler 实例与 WebSphere 安全性运行时进行交互以验证用户密码,与活动用户注册表交互以检索用户的唯一标识和成员资格组。检索到的数据放在客户机主体集中的专用凭证集的散列表中。CallbackHandler 的 WebSphere Application Server 实现支持三项回调:
    • CallerPrincipalCallback
    • GroupPrincipalCallback
    • PasswordValidationCallback
    如果认证模块未使用 CallbackHandler,并且 validateRequest 返回成功状态,那么 WebSphere Application Server 要求散列表实例与用户身份信息包括在 clientSubject 中,以便可以执行定制登录以获得用户的凭证。可如以下示例中所示将此散列表添加至客户机主体集:
    import java.util.Hashtable;
    import java.util.String;
    import javax.security.auth.Subject;
    import javax.security.auth.message.AuthException;
    import javax.security.auth.message.AuthStatus;
    import javax.security.auth.message.MessageInfo;
    import com.ibm.wsspi.security.registry.RegistryHelper;
    import com.ibm.wsspi.security.token.AttributeNameConstants.AttributeNameConstants;
    
    public AuthStatus validateRequest(MessageInfo messageInfo, Subject clientSubject, Subject serviceSubject)
           throws AuthException {
           ...
           UserRegistry reg = RegistryHelper.getUserRegistry(null);
           String uniqueid = reg.getUniqueUserID(username);
    
           Hashtable hashtable = new Hashtable();
           hashtable.put(AttributeNameConstants.WSCREDENTIAL_UNIQUEID, uniqueid);
           hashtable.put(AttributeNameConstants.WSCREDENTIAL_SECURITYNAME, username);
           hashtable.put(AttributeNameConstants.WSCREDENTIAL_PASSWORD, password);
           hashtable.put(AttributeNameConstants.WSCREDENTIAL_GROUPS, groupList); //optional
           clientSubject.getPrivateCredentials().add(hashtable);
           ...
    }

    有关散列表需求和定制登录的更多信息,请阅读“为 JAAS 的系统登录配置开发定制登录模块”。

    要支持 Java Servlet 3.0 规范的认证方法,必须将以下逻辑添加至 ServerAuthModule 实现类中的 validateRequest 方法:
    import java.util.Map;
    import javax.security.auth.Subject;
    import javax.security.auth.message.AuthException;
    import javax.security.auth.message.AuthStatus;
    import javax.security.auth.message.MessageInfo;
    import javax.servlet.http.HttpServletRequest;
    
    public AuthStatus validateRequest(MessageInfo messageInfo, Subject clientSubject, Subject serviceSubject)
           throws AuthException {
           ...
           Map msgMap = messageInfo.getMap();
    
          if ("authenticate".equalsIgnoreCase(msgMap.get("com.ibm.websphere.jaspi.request"))) {
                  // this request is for the authenticate method
                  String authHeader
                       = ((HttpServletRequest) messageInfo.getRequestMessage()).getHeader("Authorization");
                  if (authHeader == null) {
                       // The user has not provided a username and password yet, return
                       // AuthStatus.SEND_CONTINUE to challenge
                  } 
                  else {
                       // Authenticate using the user name and password in the authentication header.
                  }
           }
           else {
                  // This is not a Servlet 3.0 authenticate request; handle as usual.
           }
           ...
    }
  5. 编译新创建的所有类。
    必须在类路径中指定 WebSphere Application Server 安装版本中的下列 JAR 文件才能成功编译这些新类:
  6. 创建一个具有已编译的类的 JAR 文件。
    根据需求,可以将此 JAR 文件放在下列三个位置之一:
    • app_server_root/lib

      此位置始终在 WebSphere Application Server 类装入器的类路径上。通过使用此位置,可以将一组 Web 模块或应用程序的提供者注册为所有 Web 模块和应用程序的单元或域缺省提供者,并且可以将其手动注册为持久提供者。

    • 共享库

      将提供者 JAR 文件放在 WebSphere Application Server 系统上的任何位置。配置一个指向该 JAR 的共享库,并将该共享库添加至应用程序或服务器类路径。在共享库中,可以为一组 Web 模块或应用程序注册提供者,但是无法将该提供者用作单元或域缺省提供者。也无法将其注册为持久提供者,这是因为在服务器启动期间,该共享库不在用于提供者注册的类路径中。有关配置共享库的更多信息,请阅读“创建共享库”。

    • 嵌入在应用程序中

      将提供者 JAR 文件作为实用程序 JAR 包括在应用程序的 EAR 文件中,或者将已编译的类文件嵌入在 Web 模块 WAR 中。只要类包括在 Web 模块的类路径中,就可为应用程序中的 Web 模块注册嵌入式提供者。无法将此提供者用作单元或域缺省提供者,也无法将其注册为持久提供者。在服务器启动期间,应用程序中的类不可用于提供者注册。

  7. 使用管理控制台或者管理脚本在安全性配置中配置提供者。

    有关更多信息,请阅读使用管理控制台来配置新的 JASPI 认证提供程序 或者AdminTask 对象的 JaspiManagement 命令组


指示主题类型的图标 任务主题



时间戳记图标 最近一次更新时间: last_date
http://www14.software.ibm.com/webapp/wsbroker/redirect?version=cord&product=was-nd-mp&topic=tsec_jaspi_develop
文件名:tsec_jaspi_develop.html