针对 JAAS 开发用于系统登录配置的定制登录模块
对于 WebSphere® Application Server,存在多个用于配置系统登录的 Java™ 认证和授权服务 (JAAS) 插入点。WebSphere Application Server 使用系统登录配置来认证入局请求、出局请求以及内部服务器登录。
关于此任务
- WEB_INBOUND
- RMI_OUTBOUND
- RMI_INBOUND
- DEFAULT
过程
- 使用 WEB_INBOUND 登录配置认证 Web 请求。
WEB_INBOUND 登录配置认证 Web 请求。
有关 WEB_INBOUND 配置(包括其关联的回调)的更多详细信息,请参阅Java 认证和授权服务的系统登录配置条目设置中的“RMI_INBOUND、WEB_INBOUND、DEFAULT”。
图 1 使用信任关联拦截器 (TAI) 显示配置示例,此信任关联拦截器用传递到 WEB_INBOUND 登录配置的初始信息创建主体集。如果未配置信任关联拦截器,那么认证进程直接转至 WEB_INBOUND 系统登录配置,此登录配置由图 1 中的所有登录模块组成。图 1 显示您可以插入定制登录模块的位置以及需要 ltpaLoginModule 以及 wsMapDefaultInboundLoginModule 登录模块的位置。图 1. WEB_INBOUND 登录配置 - 使用 RMI_OUTBOUND 登录配置处理出站请求。
RMI_OUTBOUND 登录配置是用于处理出站请求的插入点。WebSphere Application Server 使用此插入点以根据传递进来的调用主体集和其他安全上下文信息(例如,传播令牌)创建往下游发送的已序列化的信息。定制登录模块可以使用此插入点更改标识。有关更多信息,请参阅配置到不同目标域的出站标识映射。图 2 显示您可以插入定制登录模块的位置,并显示需要 wsMapCSIv2OutboundLoginModule 登录模块的位置。
图 2. RMI_OUTBOUND 登录配置有关 RMI_OUTBOUND 登录配置(包括其关联的回调)的更多信息,请参阅Java 认证和授权服务的系统登录配置条目设置中的“RMI_OUTBOUND”。
- 使用 RMI_INBOUND 登录配置处理企业 Bean 请求的入站认证。
RMI_INBOUND 登录配置是处理企业 Bean 请求的入站认证的插入点。WebSphere Application Server 将此插入点用于初始登录或传播登录。有关这两种登录类型的更多信息,请参阅安全性属性传播。在传播登录期间,此插入点用于反序列化从上游服务器接收的信息。定制登录模块可以使用此插入点更改标识、处理定制令牌、将定制对象添加到主体集等等。要获取使用散列表对象(在图 3 中引用)更改标识的更多信息,请参阅配置入站标识映射。图 3 显示您可以插入定制登录模块的位置,并显示需要 ltpaLoginModule 和 wsMapDefaultInboundLoginModule 登录模块的位置。
图 3. RMI_INBOUND 登录配置有关 RMI_INBOUND 登录配置(包括其关联的回调)的更多信息,请参阅Java 认证和授权服务的系统登录配置条目设置中的“RMI_INBOUND、WEB_INBOUND、DEFAULT”。
- 使用 DEFAULT 登录配置处理所有其他类型的认证请求。 DEFAULT 登录配置
DEFAULT 登录配置是处理所有其他认证请求类型(包括管理 SOAP 请求和服务器标识的内部认证)的插入点。传播登录通常不在此插入点上发生。
有关 DEFAULT 登录配置(包括其关联的回调)的更多信息,请参阅Java 认证和授权服务的系统登录配置条目设置中的“RMI_INBOUND、WEB_INBOUND、DEFAULT”。
- 开发登录配置逻辑以识别特定信息何时存在及如何使用该信息。 编写登录模块当您编写插入到 WebSphere Application Server 应用程序登录或系统登录配置的登录模块时,请阅读位于:http://java.sun.com/products/jaas 的 JAAS 编程模型。JAAS 编程模型提供有关 JAAS 的基本信息。然而,在编写用于 WebSphere Application Server 环境的登录模块前,请先阅读以下部分:
- 可用的回调
- 共享状态变量
- 初始登录对传播登录
- 样本定制登录模块
可用回调
每个登录配置必须记录由登录配置认出的回调。但是,回调不总是已传递的数据。登录配置必须包含逻辑以了解何时存在特定信息以及如何使用此信息。例如,如果您写可以插入到先前提到过的所有四种预配置的系统登录配置的定制登录模块,那么可以提供三组回调以认证请求。出于其他原因,可能存在其他回调,包括传播和使其他信息可用于登录配置。
可以在以下各组合中提供登录信息:- 用户名 (NameCallback) 和密码 (PasswordCallback)
- 此信息是典型认证组合。
- 仅用户名 (NameCallback)
- 此信息用于身份断言、信任关联拦截器 (TAI) 登录和证书登录。
- 令牌 (WSCredTokenCallbackImpl)
- 此信息用于轻量级第三方认证 (LTPA) 令牌验证。
- 传播令牌列表 (WSTokenHolderCallback)
- 此信息用于传播登录。
前三个组合用于典型认证。但是,除了前三个信息组合之一外,还存在 WSTokenHolderCallback 回调时,此登录称为传播登录。传播登录意味着某些安全性属性从另一个服务器传播到此服务器。如果认证信息验证成功,那么服务器可以复用这些安全性属性。在某些情况下,WSTokenHolderCallback 回调可能不具有足够的属性以用于完全登录。请检查 WSTokenHolderCallback 回调上的 requiresLogin 方法以确定是否需要新登录。您始终可以忽略由 requiresLogin 方法返回的信息,但结果可能复制信息。以下列表包含可以在系统登录配置中存在的回调。此列表包括回调名称和职责描述。- callbacks[0] = new javax.security.auth.callback.NameCallback(“Username: ”);
- 此回调处理程序收集用于登录的用户名。结果可以是用于基本认证登录(用户名和密码)的用户名或用于身份断言登录的用户名。
- callbacks[1] = new javax.security.auth.callback.PasswordCallback(“Password: ”, false);
- 此回调处理程序收集用于登录的密码。
- callbacks[2] = new com.ibm.websphere.security.auth.callback.WSCredTokenCallbackImpl(“Credential Token:”);
- 此回调处理程序收集用于登录的轻量级第三方认证 (LTPA) 令牌或其他令牌类型。通常,当不存在用户名和密码时出现此回调处理程序。
- callbacks[3] = new com.ibm.wsspi.security.auth.callback.WSTokenHolderCallback(“Authz Token List:”);
- 此回调处理程序收集 TokenHolder 对象的 ArrayList,这些对象是使用公共安全互操作性 V2 (CSIv2) 授权令牌作为输入来调用 WSOpaqueTokenHelper.createTokenHolderListFromOpaqueToken API 返回的。
- callbacks[4] = new com.ibm.websphere.security.auth.callback.WSServletRequestCallback(“HttpServletRequest:” );
- 此回调处理程序收集 HTTP servlet 请求对象(如果存在)。此回调处理程序使登录模块从 HTTP 请求获取信息以用于登录中,仅 WEB_INBOUND 登录配置中才存在此处理程序。
- callbacks[5] = new com.ibm.websphere.security.auth.callback.WSServletResponseCallback(“HttpServletResponse:”);
- 此回调处理程序收集 HTTP servlet 响应对象(如果存在)。此回调处理程序允许登录模块将信息放入 HTTP 响应中作为登录结果。此情况的示例可能会将 SingleSignonCookie cookie 添加到响应。仅 WEB_INBOUND 登录配置中才存在此回调处理程序。
- callbacks[6] = new com.ibm.websphere.security.auth.callback.WSAppContextCallback(“ApplicationContextCallback:”);
- 此回调处理程序收集在登录期间使用的 Web 应用程序上下文。此回调处理程序包括一个 HashMap 对象,该对象包含应用程序名称和重定向 Web 地址(如果存在的话)。仅 WEB_INBOUND 登录配置中才存在此回调处理程序。
- callbacks[7] = new WSRealmNameCallbackImpl(“Realm Name:”, default_realm);
- 此回调处理程序收集领域名以获取登录信息。并不会始终提供领域信息。如果未提供领域信息,那么假定它是当前领域。
- callbacks[8] = new WSX509CertificateChainCallback(“X509Certificate[]:”);
- 如果登录源是通过了 SSL 客户机认证的 X509Certificate,那么此回调处理程序包含安全套接字层已验证的证书。ltpaLoginModule 调用与 V6.1 之前的 WebSphere Application Server 发行版相同的映射函数。但是,将它传递到登录中将使定制登录模块有机会以定制方式映射该证书。然后,它执行散列表登录。请参阅配置入站标识映射,以获取有关散列表登录的更多信息。
- 使用共享状态变量在登录阶段期间共享登录模块之间的信息。 如果您要访问在登录期间 WebSphere Application Server 创建的对象,请参阅以下各共享状态变量。在以登录模块中设置这些变量:ltpaLoginModule、swamLoginModule 和 wsMapDefaultInboundLoginModule。
- 共享状态变量
- com.ibm.wsspi.security.auth.callback.Constants.WSPRINCIPAL_KEY
- 用途
- 指定 com.ibm.websphere.security.auth.WSPrincipal 对象。请参阅 WebSphere Application Server API 文档,以获取应用程序编程接口 (API) 用法。此共享状态变量供只读使用。不要在定制登录模块的共享状态中设置此变量。
- 设置了变量的登录模块
- ltpaLoginModule、swamLoginModule 和 wsMapDefaultInboundLoginModule
- 共享状态变量
- com.ibm.wsspi.security.auth.callback.Constants.WSCREDENTIAL_KEY
- 用途
- 指定 com.ibm.websphere.security.cred.WSCredential 对象。请参阅 WebSphere Application Server API 文档,以获取 API 用法。此共享状态变量供只读使用。不要在定制登录模块的共享状态中设置此变量。
- 设置了变量的登录模块
- wsMapDefaultInboundLoginModule
- 共享状态变量
- com.ibm.wsspi.security.auth.callback.Constants.WSAUTHZTOKEN_KEY
- 用途
- 指定缺省 com.ibm.wsspi.security.token.AuthorizationToken 对象。登录模块可以使用此对象设置在 wsMapDefaultInboundLoginModule 登录模块后插入的定制属性。此处设置的信息往下游传播,而且可用于应用程序。请参阅 WebSphere Application Server API 文档,以获取 API 用法。
初始登录对传播登录
如先前所提到的,由于以下各原因某些登录被认为是初始登录:- 这是首次将认证信息提供给 WebSphere Application Server。
- 从不传播安全性属性的服务器接收登录信息,因此必须从用户注册表收集此信息。
当存在 WSTokenHolderCallback 回调而且包含来自发送服务器的足够信息以重新创建 WebSphere Application Server 运行时需要的所有必需的对象时,认为其他登录是传播登录。如果存在 WebSphere Application Server 运行时的足够信息,那么您可以添加到主体集的信息可能存在于前一次登录中。要验证对象是否存在,可以访问 WSTokenHolderCallback 回调中存在的 ArrayList 对象,并通过此列表进行搜索,查看每个 TokenHolder getName 方法。此搜索用于确定 WebSphere Application Server 在此次登录期间是否正在反序列化定制对象。请检查使用 String startsWith 方法从 getName 方法返回的类名,因为运行时可能在名称末端添加其他信息以了解在反序列化后设置哪个主体集添加定制对象。
- 编写 login() 方法以确定何时存在足够信息。
以下代码片段可以用于 login() 方法中,以确定何时存在足够信息。要获取另一个示例,请参阅配置入站标识映射。
// This is a hint provided by WebSphere Application Server that // sufficient propagation information does not exist and, therefore, // a login is required to provide the sufficient information. In this // situation, a Hashtable login might be used. boolean requiresLogin = ((com.ibm.wsspi.security.auth.callback. WSTokenHolderCallback) callbacks[1]).requiresLogin(); if (requiresLogin) { // Check to see if your object exists in the TokenHolder list, if not, add it. java.util.ArrayList authzTokenList = ((WSTokenHolderCallback) callbacks[6]). getTokenHolderList();boolean found = false; if (authzTokenList != null) { Iterator tokenListIterator = authzTokenList.iterator(); while (tokenListIterator.hasNext()) { com.ibm.wsspi.security.token.TokenHolder th = (com.ibm.wsspi.security.token. TokenHolder) tokenListIterator.next(); if (th != null && th.getName().startsWith("com.acme.myCustomClass")) { found=true; break; } } if (!found) { // go ahead and add your custom object. } } } else { // This code indicates that sufficient propagation information is present. // User registry calls are not needed by WebSphere Application Server to // create a valid Subject. This code might be a no-op in your login module. }
样本定制登录模块
可以使用以下样本获取有关如何使用某些回调和共享的状态变量的观点。
{ // Defines your login module variables com.ibm.wsspi.security.token.AuthenticationToken customAuthzToken = null; com.ibm.wsspi.security.token.AuthenticationToken defaultAuthzToken = null; com.ibm.websphere.security.cred.WSCredential credential = null; com.ibm.websphere.security.auth.WSPrincipal principal = null; private javax.security.auth.Subject _subject; private javax.security.auth.callback.CallbackHandler _callbackHandler; private java.util.Map _sharedState; private java.util.Map _options; public void initialize(Subject subject, CallbackHandler callbackHandler, Map sharedState, Map options) { _subject = subject; _callbackHandler = callbackHandler; _sharedState = sharedState; _options = options; } public boolean login() throws LoginException { boolean succeeded = true; // Gets the CALLBACK information javax.security.auth.callback.Callback callbacks[] = new javax.security. auth.callback.Callback[7]; callbacks[0] = new javax.security.auth.callback.NameCallback( "Username: "); callbacks[1] = new javax.security.auth.callback.PasswordCallback( "Password: ", false); callbacks[2] = new com.ibm.websphere.security.auth.callback. WSCredTokenCallbackImpl ("Credential Token: "); callbacks[3] = new com.ibm.wsspi.security.auth.callback. WSServletRequestCallback ("HttpServletRequest: "); callbacks[4] = new com.ibm.wsspi.security.auth.callback. WSServletResponseCallback ("HttpServletResponse: "); callbacks[5] = new com.ibm.wsspi.security.auth.callback. WSAppContextCallback ("ApplicationContextCallback: "); callbacks[6] = new com.ibm.wsspi.security.auth.callback. WSTokenHolderCallback ("Authz Token List: "); try { callbackHandler.handle(callbacks); } catch (Exception e) { // Handles exceptions throw new WSLoginFailedException (e.getMessage(), e); } // Sees which callbacks contain information uid = ((NameCallback) callbacks[0]).getName(); char password[] = ((PasswordCallback) callbacks[1]).getPassword(); byte[] credToken = ((WSCredTokenCallbackImpl) callbacks[2]).getCredToken(); javax.servlet.http.HttpServletRequest request = ((WSServletRequestCallback) callbacks[3]).getHttpServletRequest(); javax.servlet.http.HttpServletResponse response = ((WSServletResponseCallback) callbacks[4]).getHttpServletResponse(); java.util.Map appContext = ((WSAppContextCallback) callbacks[5]).getContext(); java.util.List authzTokenList = ((WSTokenHolderCallback) callbacks[6]).getTokenHolderList(); // Gets the SHARED STATE information principal = (WSPrincipal) _sharedState.get(com.ibm.wsspi.security. auth.callback.Constants.WSPRINCIPAL_KEY); credential = (WSCredential) _sharedState.get(com.ibm.wsspi.security. auth.callback.Constants.WSCREDENTIAL_KEY); defaultAuthzToken = (AuthorizationToken) _sharedState.get(com.ibm. wsspi.security.auth.callback.Constants.WSAUTHZTOKEN_KEY); // What you tend to do with this information depends upon the scenario // that you are trying to accomplish. This example demonstrates how to // access various different information: // - Determine if a login is initial versus propagation // - Deserialize a custom authorization token (For more information, see // 安全性属性传播 // - Add a new custom authorization token (For more information, see // 安全性属性传播 // - Look for a WSCredential and read attributes, if found. // - Look for a WSPrincipal and read attributes, if found. // - Look for a default AuthorizationToken and add attributes, if found. // - Read the header attributes from the HttpServletRequest, if found. // - Add an attribute to the HttpServletResponse, if found. // - Get the web application name from the appContext, if found. // - Determines if a login is initial versus propagation. This is most // useful when login module is first. boolean requiresLogin = ((WSTokenHolderCallback) callbacks[6]).requiresLogin(); // initial login - asserts privilege attributes based on user identity if (requiresLogin) { // If you are validating a token from another server, there is an // application programming interface (API) to get the uniqueID from it. if (credToken != null && uid == null) { try { String uniqueID = WSSecurityPropagationHelper. validateLTPAToken(credToken); String realm = WSSecurityPropagationHelper.getRealmFromUniqueID (uniqueID); // Now set it to the UID so you can use that to either map or // login with. uid = WSSecurityPropagationHelper.getUserFromUniqueID (uniqueID); } catch (Exception e) { // handle exception } } // Adds a Hashtable to shared state. // Note: You can perform custom mapping on the NameCallback value returned // to change the identity based upon your own mapping rules. uid = mapUser (uid); // Gets the default InitialContext for this server. javax.naming.InitialContext ctx = new javax.naming.InitialContext(); // Gets the local UserRegistry object. com.ibm.websphere.security.UserRegistry reg = (com.ibm.websphere.security. UserRegistry) ctx.lookup("UserRegistry"); // Gets the user registry uniqueID based on the uid specified in the // NameCallback. String uniqueid = reg.getUniqueUserId(uid); uid = WSSecurityPropagationHelper.getUserFromUniqueID (uniqueID); // Gets the display name from the user registry based on the uniqueID. String securityName = reg.getUserSecurityName(uid); // Gets the groups associated with this uniqueID. java.util.List groupList = reg.getUniqueGroupIds(uid); // Creates the java.util.Hashtable with the information you gathered from // the UserRegistry. java.util.Hashtable hashtable = new java.util.Hashtable(); hashtable.put(com.ibm.wsspi.security.token.AttributeNameConstants. WSCREDENTIAL_UNIQUEID, uniqueid); hashtable.put(com.ibm.wsspi.security.token.AttributeNameConstants. WSCREDENTIAL_SECURITYNAME, securityName); hashtable.put(com.ibm.wsspi.security.token.AttributeNameConstants. WSCREDENTIAL_GROUPS, groupList); // Adds a cache key that is used as part of the lookup mechanism for // the created Subject. The cache key can be an Object, but should // implement the toString() method. Make sure the cacheKey contains // enough information to scope it to the user and any additional // attributes that you use. If you do not specify this property the // Subject is scoped to the WSCREDENTIAL_UNIQUEID returned, by default. hashtable.put(com.ibm.wsspi.security.token.AttributeNameConstants. WSCREDENTIAL_CACHE_KEY, "myCustomAttribute" + uniqueid); // Adds the hashtable to the sharedState of the Subject. _sharedState.put(com.ibm.wsspi.security.token.AttributeNameConstants. WSCREDENTIAL_PROPERTIES_KEY,hashtable); } // propagation login - process propagated tokens else { // - Deserializes a custom authorization token. For more information, see // 安全性属性传播. // This can be done at any login module plug in point (first, // middle, or last). if (authzTokenList != null) { // Iterates through the list looking for your custom token for (int i=0; i<authzTokenList.size(); i++) { TokenHolder tokenHolder = (TokenHolder)authzTokenList.get(i); // Looks for the name and version of your custom AuthorizationToken // implementation if (tokenHolder.getName().equals("com.ibm.websphere.security.token. CustomAuthorizationTokenImpl") && tokenHolder.getVersion() == 1) { // Passes the bytes into your custom AuthorizationToken constructor // to deserialize customAuthzToken = new com.ibm.websphere.security.token. CustomAuthorizationTokenImpl(tokenHolder.getBytes()); } } } // - Adds a new custom authorization token (For more information, // see 安全性属性传播) // This can be done at any login module plug in point (first, middle, // or last). else { // Gets the PRINCIPAL from the default AuthenticationToken. This must // match all of the tokens. defaultAuthToken = (com.ibm.wsspi.security.token.AuthenticationToken) sharedState.get(com.ibm.wsspi.security.auth.callback.Constants. WSAUTHTOKEN_KEY); String principal = defaultAuthToken.getPrincipal(); // Adds a new custom authorization token. This is an initial login. // Pass the principal into the constructor customAuthzToken = new com.ibm.websphere.security.token. CustomAuthorizationTokenImpl(principal); // Adds any initial attributes if (customAuthzToken != null) { customAuthzToken.addAttribute("key1", "value1"); customAuthzToken.addAttribute("key1", "value2"); customAuthzToken.addAttribute("key2", "value1"); customAuthzToken.addAttribute("key3", "something different"); } } } // - Looks for a WSCredential and read attributes, if found. // This is most useful when plugged in as the last login module. if (credential != null) { try { // Reads some data from the credential String securityName = credential.getSecurityName(); java.util.ArrayList = credential.getGroupIds(); } catch (Exception e) { // Handles exceptions throw new WSLoginFailedException (e.getMessage(), e); } } // - Looks for a WSPrincipal and read attributes, if found. // This is most useful when plugged as the last login module. if (principal != null) { try { // Reads some data from the principal String principalName = principal.getName(); } catch (Exception e) { // Handles exceptions throw new WSLoginFailedException (e.getMessage(), e); } } // - Looks for a default AuthorizationToken and add attributes, if found. // This is most useful when plugged in as the last login module. if (defaultAuthzToken != null) { try { // Reads some data from the defaultAuthzToken String[] myCustomValue = defaultAuthzToken.getAttributes ("myKey"); // Adds some data if not present in the defaultAuthzToken if (myCustomValue == null) defaultAuthzToken.addAttribute ("myKey", "myCustomData"); } catch (Exception e) { // Handles exceptions throw new WSLoginFailedException (e.getMessage(), e); } } // - Reads the header attributes from the HttpServletRequest, if found. // This can be done at any login module plug in point (first, middle, // or last). if (request != null) { java.util.Enumeration headerEnum = request.getHeaders(); while (headerEnum.hasMoreElements()) { System.out.println ("Header element: " + (String)headerEnum.nextElement()); } } // - Adds an attribute to the HttpServletResponse, if found // This can be done at any login module plug in point (first, middle, // or last). if (response != null) { response.addHeader ("myKey", "myValue"); } // - Gets the web application name from the appContext, if found // This can be done at any login module plug in point (first, middle, // or last). if (appContext != null) { String appName = (String) appContext.get(com.ibm.wsspi.security.auth. callback.Constants.WEB_APP_NAME); } return succeeded; } public boolean commit() throws LoginException { boolean succeeded = true; // Add any objects here that you have created and belong in the // Subject. Make sure the objects are not already added. If you added // any sharedState variables, remove them before you exit. If the abort() // method gets called, make sure you cleanup anything added to the // Subject here. if (customAuthzToken != null) { // Sets the customAuthzToken token into the Subject try { // Do this in a doPrivileged code block so that application code // does not need to add additional permissions java.security.AccessController.doPrivileged(new java.security.PrivilegedAction() { public Object run() { try { // Adds the custom authorization token if it is not // null and not already in the Subject if ((customAuthzTokenPriv != null) && (!_subject.getPrivateCredentials().contains(customAuthzTokenPriv))) { _subject.getPrivateCredentials().add(customAuthzTokenPriv); } } catch (Exception e) { throw new WSLoginFailedException (e.getMessage(), e); } return null; } }); } catch (Exception e) { throw new WSLoginFailedException (e.getMessage(), e); } } return succeeded; } public boolean abort() throws LoginException { boolean succeeded = true; // Makes sure to remove all objects that have already been added (both into the // Subject and shared state). if (customAuthzToken != null) { // remove the customAuthzToken token from the Subject try { final AuthorizationToken customAuthzTokenPriv = customAuthzToken; // Do this in a doPrivileged block so that application code does not need // to add additional permissions java.security.AccessController.doPrivileged(new java.security.PrivilegedAction() { public Object run() { try { // Removes the custom authorization token if it is not // null and not already in the Subject if ((customAuthzTokenPriv != null) && (_subject.getPrivateCredentials(). contains(customAuthzTokenPriv))) { _subject.getPrivateCredentials(). remove(customAuthzTokenPriv); } } catch (Exception e) { throw new WSLoginFailedException (e.getMessage(), e); } return null; } }); } catch (Exception e) { throw new WSLoginFailedException (e.getMessage(), e); } } return succeeded; } public boolean logout() throws LoginException { boolean succeeded = true; // Makes sure to remove all objects that have already been added // (both into the Subject and shared state). if (customAuthzToken != null) { // Removes the customAuthzToken token from the Subject try { final AuthorizationToken customAuthzTokenPriv = customAuthzToken; // Do this in a doPrivileged code block so that application code does // not need to add additional permissions java.security.AccessController.doPrivileged(new java.security. PrivilegedAction() { public Object run() { try { // Removes the custom authorization token if it is not null and not // already in the Subject if ((customAuthzTokenPriv != null) && (_subject. getPrivateCredentials(). contains(customAuthzTokenPriv))) { _subject.getPrivateCredentials().remove(customAuthzTokenPriv); } } catch (Exception e) { throw new WSLoginFailedException (e.getMessage(), e); } return null; } }); } catch (Exception e) { throw new WSLoginFailedException (e.getMessage(), e); } } return succeeded; } }
- 配置定制登录模块的系统登录。
在您开发系统登录配置的定制登录模块后,可使用管理控制台或使用 wsadmin 实用程序配置系统登录。要使用管理控制台来配置系统登录,请单击安全性 > 全局安全性。在“Java 认证和授权服务”下,单击系统登录。有关将 wsadmin 实用程序用于系统登录配置的更多信息,请参阅定制服务器端 Java 认证和授权服务认证及登录配置。另请参阅该文章,以了解有关系统登录模块的信息及确定是否添加其他登录模块。


http://www14.software.ibm.com/webapp/wsbroker/redirect?version=cord&product=was-nd-mp&topic=tsec_jaascustlogmod
文件名:tsec_jaascustlogmod.html