使用定制身份库配置安全性

JSR-375 规范提供了使用定制身份库的选项。 您可以使用此选项来实现自己的身份库,并精确控制如何执行用户认证。

有关 JSR-375的更多信息,请参阅 Enterprise Java Security API

关于此任务

按照以下步骤,通过使用自定义身份存储、 HTTP 身份验证机制以及将已验证身份映射到将用于 CICS® 任务的 SAF 用户 ID,对 Liberty 网络应用程序进行身份验证。

过程

  1. 根据您使用的是 Java EE 8、Jakarta EE 9 还是 Jakarta EE 10,将 appSecurity-3.0 功能、 appSecurity-4.0 功能或 appSecurity-5.0 功能添加到 server.xml

  2. 确保已启用 CDI 注释文件扫描。 缺省情况下, CICS® 在 server.xml中将其禁用。 您可以通过以下方法确保对 Web 应用程序启用 CDI 注释文件扫描:
    • 将 CDI 功能部件的相关版本添加到 Liberty 功能部件管理器列表。
    • beans.xml 文件添加到 .war 文件的 WEB-INF 文件夹。
  3. 创建 Java™ 类以处理定制身份存储逻辑并将其构建到 WAR 文件中。
    1. 通过创建实现 IdentityStore 接口的类来创建定制身份库对象,如以下示例中所示:
      @ApplicationScoped
      public class MyIdentityStore implements IdentityStore 
      {	
          public CredentialValidationResult validate(UsernamePasswordCredential userCredential) 
          { 
              if (userCredential.compareTo("USERID", "PASSWORD")) 
              {
                  return new CredentialValidationResult("USERID", new HashSet<>(Arrays.asList("ROLE1","ROLE2")));
              }
              return CredentialValidationResult.INVALID_RESULT;
          }
      }
      
    2. 创建与该身份存储相关联的 HTTP 身份验证机制,与上一步创建的身份存储类一起使用:
      @ApplicationScoped
      public class MyAuthMechanism implements HttpAuthenticationMechanism 
      {
      
          @Inject
          private IdentityStoreHandler idStoreHandler;
      
          public AuthenticationStatus validateRequest(HttpServletRequest req, HttpServletResponse res, HttpMessageContext context) 
          {
              CredentialValidationResult result = idStoreHandler.validate( 
                  new UsernamePasswordCredential(
                      req.getParameter("name"),
                      req.getParameter("password")));
              if (result.getStatus() == CredentialValidationResult.Status.VALID) 
              {
                  return context.notifyContainerAboutLogin(result);
              } 
              else 
              {
                  return context.responseUnauthorized();
              }
          }
      }
      
  4. 创建用于定义对身份库实现返回的角色的访问权的 servlet。 例如:
    @WebServlet("/home")
    @ServletSecurity(@HttpConstraint(rolesAllowed = "ROLE1"))
    public class Servlet extends HttpServlet {...}
    

    如果不按步骤 3b 开发自己的 HTTP 身份验证机制,也可以在 servlet 类中添加 HTTP 基本身份验证或登录表注解:

    @BasicAuthenticationMechanismDefinition(realmName="defaultRealm")
  5. 确定是否将身份库凭证映射到 SAF 用户标识。

    如果希望 CICS 任务在从定制身份库映射的特定 SAF 用户下运行,那么需要执行以下步骤:

    1. <safRegistry/> 元素添加到 server.xml 以启用 SAF 支持。
    2. cicsts:security-1.0 功能部件添加到 server.xml 以确保将 Liberty 主体集声明为 CICS 任务用户标识。
    3. 通过设置以下元素来配置 server.xml 中分布式身份的映射。
      <safCredentials mapDistributedIdentities="true" suppressAuthFailureMessages="false"/>
    4. 使用 RACMAP 命令创建从定制注册表到 SAF 用户标识的身份映射。
      在以下示例中, customUserid 是来自定制注册表的身份, safUserid 是用于在 Liberty 中运行的 RACF® 用户标识。 使用定制身份库时,除非被覆盖,否则注册表域名为 defaultRealm
      RACMAP ID(safUserid) MAP WITHLABEL('label-name')
      USERDIDFILTER(NAME('customUserid'))
      REGISTRY(NAME('defaultRealm'))
      
重要说明:
如果在 CICS 束中部署应用程序,那么将在 installedApps.xml 中自动设置安全角色 "cicsAllAuthenticated" ,如下所示:
<application ...>
    <application-bnd> 
        <security-role name="cicsAllAuthenticated">
            <special-subject type="ALL_AUTHENTICATED_USERS"/>
        </security-role>
    </application-bnd>
</application>

cicsAllAuthenticated 作用生效,并出现 HTTP 403 错误。 您可以从三个选项中进行选择以解决此错误:

  1. 在 CICS 束中部署,并在 @ServletSecurity rolesAllowed 注释上命名 cicsAllAuthenticated 角色。
  2. 在 CICS 束中部署,但使用 SAF 授权和 SAF 角色映射器。 使用这些选项会绕过 <application-bnd>. 中指定的角色映射
  3. 通过使用 server.xml中的 <application> 元素将应用程序直接部署到 Liberty 中,从而避免使用 CICS 束。

结果

您已成功配置定制身份库。