1.5. 创建 JAAS 域


1.5.1. Elytron 中的 JAAS 域

Java 认证和授权服务(JAAS)域 jaas-realm 是一个安全域,您可以用来在 elytron 子系统中为用户的凭证验证和分配用户角色配置自定义登录模块。

您可以使用 jaas-realm 来保护 JBoss EAP 管理界面和已部署的应用。

JAAS 域通过初始化 javax.security.auth.login.LoginContext (其使用 JAAS 配置文件中指定的登录模块)来验证用户凭据,。

登录模块是 javax.security.auth.login.LoginContext.LoginModule 接口的实现。将这些实现作为 JBoss EAP 模块添加到服务器中,并在 JAAS 配置文件中指定它们。

JAAS 配置文件示例

test { 
1

    loginmodules.CustomLoginModule1 optional; 
2

    loginmodules.CustomLoginModule2 optional myOption1=true myOption2=exampleOption; 
3

};
Copy to Clipboard Toggle word wrap

1
配置 jaas-realm 时使用的条目的名称。
2
使用其可选标记登录模块。您可以使用 JAAS 定义的所有标志。如需更多信息,请参阅 Oracle Java SE 文档中的 JAAS 登录配置文件
3
使用其可选标志和选项登录模块。
在登录模块中与属性映射和角色关联的主题的主体

您可以使用 主题 的主体将属性添加到从登录模块获取的身份中。主题 是正被身份验证的用户,主体是标识符,如用户名,包含在主体内。

Elytron 获取和映射身份,如下所示:

  • 登录模块使用 javax.security.auth.Subject 代表用户,正被身份验证的 主题
  • 主题 可以有多个 java.security.Principal 实例 principal 与之关联。
  • Elytron 使用 org.wildfly.security.auth.server.SecurityIdentity 来代表经过身份验证的用户。Elytron 将 主题 映射到SecurityIdentity

主题的 主体 被映射到具有以下规则的安全身份的属性:

  • 属性的 key主体 的简单类名称,可通过 principal.getClass().getSimpleName() 调用获得。
  • value主体 的名称,可通过 principal.getName() 调用获得。
  • 对于同一类型的 主体,这些值会附加到属性键下的集合中。

1.5.2. 开发自定义 JAAS 登录模块

您可以创建自定义 Java 身份验证和授权服务(JAAS)登录模块来实现自定义身份验证和授权功能。

您可以通过 Elytron 子系统中的 jaas-realm ,使界面和部署的应用程序。登录模块不是部署的一部分,您可以将它们作为 JBoss EAP 模块包含在内。

注意

以下流程仅作为示例提供。如果您已有要保护的应用程序,则可以跳过这些步骤,直接来到 向应用程序添加身份验证和授权

要创建自定义 Java 身份验证和授权服务(JAAS)登录模块,请创建一个具有所需依赖项和目录结构的 Maven 项目。

先决条件

流程

  1. 在 CLI 中使用 mvn 命令来建立一个 Maven 项目。此命令为项目创建目录结构,以及 pom.xml 配置文件。

    语法

    $ mvn archetype:generate \
    -DgroupId=<group-to-which-your-application-belongs> \
    -DartifactId=<name-of-your-application> \
    -DarchetypeGroupId=org.apache.maven.archetypes \
    -DarchetypeArtifactId=maven-archetype-simple \
    -DinteractiveMode=false
    Copy to Clipboard Toggle word wrap

    Example

    $ mvn archetype:generate \
    -DgroupId=com.example.loginmodule \
    -DartifactId=example-custom-login-module \
    -DarchetypeGroupId=org.apache.maven.archetypes \
    -DarchetypeArtifactId=maven-archetype-simple \
    -DinteractiveMode=false
    Copy to Clipboard Toggle word wrap

  2. 导航到应用程序根目录。

    语法

    $ cd <name-of-your-application>
    Copy to Clipboard Toggle word wrap

    Example

    $ cd example-custom-login-module
    Copy to Clipboard Toggle word wrap

  3. 将生成的 pom.xml 文件的内容替换为以下文本:

    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
    
        <groupId>custom.loginmodules</groupId>
        <artifactId>custom-login-modules</artifactId>
        <version>1.0</version>
        <dependencies>
            <dependency>
                <groupId>org.wildfly.security</groupId>
                <artifactId>wildfly-elytron</artifactId>
                <version>1.17.2.Final</version>
            </dependency>
            <dependency>
                <groupId>jakarta.security.enterprise</groupId>
                <artifactId>jakarta.security.enterprise-api</artifactId>
                <version>3.0.0</version>
            </dependency>
        </dependencies>
    
        <properties>
            <maven.compiler.source>11</maven.compiler.source>
            <maven.compiler.target>11</maven.compiler.target>
        </properties>
    
    </project>
    Copy to Clipboard Toggle word wrap
  4. 删除目录 sitetest,因为本例不需要它们。

    $ rm -rf src/site/
    $ rm -rf src/test/
    Copy to Clipboard Toggle word wrap

验证

  • 在应用程序根目录中,输入以下命令:

    $ mvn install
    Copy to Clipboard Toggle word wrap

    您会看到类似如下的输出:

    ...
    [INFO] ------------------------------------------------------------------------
    [INFO] BUILD SUCCESS
    [INFO] ------------------------------------------------------------------------
    [INFO] Total time: 1.404 s
    [INFO] Finished at: 2022-04-28T13:55:18+05:30
    [INFO] ------------------------------------------------------------------------
    Copy to Clipboard Toggle word wrap

现在,您可以创建自定义的 JAAS 登录模块。

1.5.2.2. 创建自定义的 JAAS 登录模块

通过创建实现 javax.security.auth.spi.LoginModule 接口的类来创建自定义的 Java 身份验证和授权服务(JAAS)登录模块。此外,为自定义登录模块创建具有志和选项的 JAAS 配置文件。

在此过程中,<application_home> 指向包含应用程序 pom.xml 配置文件的目录。

先决条件

流程

  1. 创建一个用于存储 Java 文件的目录。

    语法

    $ mkdir -p src/main/java/<path_based_on_artifactID>
    Copy to Clipboard Toggle word wrap

    Example

    $ mkdir -p src/main/java/com/example/loginmodule
    Copy to Clipboard Toggle word wrap

  2. 导航到包含源文件的目录。

    语法

    $ cd src/main/java/<path_based_on_groupID>
    Copy to Clipboard Toggle word wrap

    Example

    $ cd src/main/java/com/example/loginmodule
    Copy to Clipboard Toggle word wrap

  3. 删除生成的文件 App.java

    $ rm App.java
    Copy to Clipboard Toggle word wrap
  4. 为自定义登录模块源创建一个文件 ExampleCustomLoginModule.java

    package com.example.loginmodule;
    
    import org.wildfly.security.auth.principal.NamePrincipal;
    
    import javax.security.auth.Subject;
    import javax.security.auth.callback.Callback;
    import javax.security.auth.callback.CallbackHandler;
    import javax.security.auth.callback.NameCallback;
    import javax.security.auth.callback.PasswordCallback;
    import javax.security.auth.callback.UnsupportedCallbackException;
    import javax.security.auth.login.LoginException;
    import javax.security.auth.spi.LoginModule;
    import java.io.IOException;
    import java.security.Principal;
    import java.util.Arrays;
    import java.util.HashMap;
    import java.util.Map;
    
    
    public class ExampleCustomLoginModule implements LoginModule {
    
        private final Map<String, char[]> usersMap = new HashMap<String, char[]>();
        private Principal principal;
        private Subject subject;
        private CallbackHandler handler;
    
        /**
         * In this example, identities are created as fixed Strings.
         *
         * The identities are:
         *    user1 has the password passwordUser1
         *    user2 has the password passwordUser2
         *
         * Use these credentials when you secure management interfaces
         * or applications with this login module.
         *
         * In a production login module, you would get the identities
         * from a data source.
         *
         */
    
        @Override
        public void initialize(Subject subject, CallbackHandler callbackHandler, Map<String, ?> sharedState, Map<String, ?> options) {
            this.subject = subject;
            this.handler = callbackHandler;
            this.usersMap.put("user1", "passwordUser1".toCharArray());
            this.usersMap.put("user2", "passwordUser2".toCharArray());
        }
    
        @Override
        public boolean login() throws LoginException {
            // obtain the incoming username and password from the callback handler
            NameCallback nameCallback = new NameCallback("Username");
            PasswordCallback passwordCallback = new PasswordCallback("Password", false);
            Callback[] callbacks = new Callback[]{nameCallback, passwordCallback};
            try {
                this.handler.handle(callbacks);
            } catch (UnsupportedCallbackException | IOException e) {
                throw new LoginException("Error handling callback: " + e.getMessage());
            }
    
            final String username = nameCallback.getName();
            this.principal = new NamePrincipal(username);
            final char[] password = passwordCallback.getPassword();
    
            char[] storedPassword = this.usersMap.get(username);
            if (!Arrays.equals(storedPassword, password)) {
                throw new LoginException("Invalid password");
            } else {
                return true;
            }
        }
    
        /**
         * user1 is assigned the roles Admin, User and Guest.
         * In a production login module, you would get the identities
         * from a data source.
         *
         */
    
        @Override
        public boolean commit() throws LoginException {
            if (this.principal.getName().equals("user1")) {
                this.subject.getPrincipals().add(new Roles("Admin"));
                this.subject.getPrincipals().add(new Roles("User"));
                this.subject.getPrincipals().add(new Roles("Guest"));
            }
            return true;
        }
    
        @Override
        public boolean abort() throws LoginException {
            return true;
        }
    
        @Override
        public boolean logout() throws LoginException {
            this.subject.getPrincipals().clear();
            return true;
        }
    
        /**
        * Principal with simple classname 'Roles' will be mapped to the identity's attribute with name 'Roles'.
        */
    
        private static class Roles implements Principal {
    
            private final String name;
    
            Roles(final String name) {
                this.name = name;
            }
    
            /**
             * @return name of the principal. This will be added as a value to the identity's attribute which has a name equal to the simple name of this class. In this example, this value will be added to the attribute with a name 'Roles'.
            */
    
            public String getName() {
                return this.name;
            }
        }
    }
    Copy to Clipboard Toggle word wrap
  5. <application_home> 目录中创建 JAAS 配置文件 JAAS-login-modules.conf

    exampleConfiguration {
    	com.example.loginmodule.ExampleCustomLoginModule optional;
    };
    Copy to Clipboard Toggle word wrap
    • exampleConfiguration 是条目名称。
    • com.example.loginmodule.ExampleCustomLoginModule 是登录模块。
    • optional 是标志。
  6. 编译登录模块。

    $ mvn package
    ...
    [INFO] ------------------------------------------------------------------------
    [INFO] BUILD SUCCESS
    [INFO] ------------------------------------------------------------------------
    [INFO] Total time: 1.321 s
    [INFO] Finished at: 2022-04-28T14:16:03+05:30
    [INFO] ------------------------------------------------------------------------
    Copy to Clipboard Toggle word wrap

现在,您可以使用登录模块来保护 JBoss EAP 管理界面和部署的应用程序。

1.5.3. 在 Elytron 中创建一个 jaas-realm

创建由 Java 认证和授权服务(JAAS)兼容自定义登录模块支持的 Elytron 安全域,来保护 JBoss EAP 服务器界面或部署的应用程序。使用安全域来创建安全域。

先决条件

流程

  1. 使用管理 CLI,将登录模块 JAR 作为模块添加到 JBoss EAP。

    语法

    module add --name=<name_of_the_login_moudle> --resources=<path_to_the_login_module_jar> --dependencies=org.wildfly.security.elytron
    Copy to Clipboard Toggle word wrap

    Example

    module add --name=exampleLoginModule  --resources=<path_to_login_module>/custom-login-modules-1.0.jar --dependencies=org.wildfly.security.elytron
    Copy to Clipboard Toggle word wrap

  2. 从登录模块和 JAAS 登录配置文件创建 jaas-realm

    语法

    /subsystem=elytron/jaas-realm=<jaas_realm_name>:add(entry=<entry-name>,path=<path_to_module_config_file>,module=<name_of_the_login_module>,callback-handler=<name_of_the_optional_callback_handler>)
    Copy to Clipboard Toggle word wrap

    Example

    /subsystem=elytron/jaas-realm=exampleSecurityRealm:add(entry=exampleConfiguration,path=<path_to_login_module>/JAAS-login-modules.conf,module=exampleLoginModule)
    Copy to Clipboard Toggle word wrap

  3. 创建一个引用 jaas-realm 的安全域。

    语法

    /subsystem=elytron/security-domain=<security_domain_name>:add(default-realm=<jaas_realm_name>,realms=[{realm=<jaas_realm_name>}],permission-mapper=default-permission-mapper)
    Copy to Clipboard Toggle word wrap

    Example

    /subsystem=elytron/security-domain=exampleSecurityDomain:add(default-realm=exampleSecurityRealm,realms=[{realm=exampleSecurityRealm}],permission-mapper=default-permission-mapper)
    {"outcome" => "success"}
    Copy to Clipboard Toggle word wrap

现在,您可以使用创建的安全域来向管理界面和应用程序添加身份验证和授权。如需更多信息,请参阅 保护管理界面和应用程序

返回顶部
Red Hat logoGithubredditYoutubeTwitter

学习

尝试、购买和销售

社区

关于红帽文档

通过我们的产品和服务,以及可以信赖的内容,帮助红帽用户创新并实现他们的目标。 了解我们当前的更新.

让开源更具包容性

红帽致力于替换我们的代码、文档和 Web 属性中存在问题的语言。欲了解更多详情,请参阅红帽博客.

關於紅帽

我们提供强化的解决方案,使企业能够更轻松地跨平台和环境(从核心数据中心到网络边缘)工作。

Theme

© 2025 Red Hat