首页 > 编程语言 >Java 高级特性——安全,jaas登陆框架(二)

Java 高级特性——安全,jaas登陆框架(二)

时间:2022-08-28 10:33:05浏览次数:74  
标签:jaas Java 框架 LoginModule 登陆 login public Principal

Java 高级特性——安全,jaas登陆框架(二)

java 提供了 jaas 框架来对用户进行鉴权,本文主要从实战方面讲述如何使用 jaas 框架,最终完成登陆模块。
阅读本文的前置知识:Java 安全框架(策略文件的使用)
注:如果使用了 Java 模块,则需将登陆用到的自定义包导出

一、Jaas 框架介绍

注:LoginModule 和 CallbackHandler 可以不是一一对应的关系,LoginModule 可以对应多个 CallbackHandler
最简单的例子就是使用 jdk 提供的类来完成登陆请求,但是一般无法满足我们的需求。
要使用 jaas 框架首先我们需要打开安全管理器,然后调用相关的登陆代码来完成登陆,在这之前,先让我们来熟悉几个用到的类或接口。

1.LoginContext 类

LoginContext 公有方法代码如下:

    public void login();
    public void logout();
    public Subject getSubject();

函数解释:

  • login():登陆
  • logout():登出
  • getSubject():获取当前登陆用户摘要信息

2.Principal类

Principal 接口,代码如下:

public interface Principal {
    public boolean equals(Object another);

    public String toString();

    public int hashCode();

    public String getName();
    /*
    * 蕴含关系,subject 是否蕴含当前的 Principal 主体
    */
    public default boolean implies(Subject subject) {
        if (subject == null)
            return false;
        return subject.getPrincipals().contains(this);
    }

该接口表示了登陆主体,代表了登陆者的身份,通过 getName() 方法返回身份名。该接口在后续重点说明。

Principal 接口 jdk 提供了下面几种实现:

  • UserPrincipal:使用用户名来表述当前登陆者的身份
  • NtUserPrincipal:也是使用用户名,不过用于 Windows 系统
  • UnixPrincipal:同上,不过用于 Unix 系统

可以通过在 policy 文件中配置 Principal 主体所拥有的权限,一个 Subject 可以有多个 Principal

LoginModule 的实现需要与 Principal 一一对应。

3.LoginModule 类

LoginModule 接口,代码如下:

public interface LoginModule {

    void initialize(Subject subject, CallbackHandler callbackHandler,
                    Map<String,?> sharedState,
                    Map<String,?> options);
    
    boolean login() throws LoginException;
    
    boolean commit() throws LoginException;
    
    boolean abort() throws LoginException;
    
    boolean logout() throws LoginException;
}

函数解释:

  • initialize():当新建一个LoginContext时,Jaas会自动创建对应的LoginModule并自动调用initialize(),可以在此函数中进行初始化操作。
  • login():当调用LoginContext.login()时,jass自动调用该函数,完成登陆,如果该函数返回为true并且没有异常抛出,则登陆成功。
  • commit():登陆成功后,调用此函数。
  • abort():如果LoginModule整体验证失败,则调用该方法。
  • logout():当调用LoginContext.logout()时,自动调用该方法。

4.主要流程

Jaas 框架,主要的流程如下:

  • 1.新建一个LoginContext,jaas通过传入的 name找到对应配置的用户名,然后利用配置信息找到对应的LoginModule并实例化。
  • 2.调用LoginContext.login()方法,jaas 会回调 LoginModule.login()方法进行登陆,如果该方法返回为true并且没有抛出异常,则登陆成功。
  • 3.如果用户登陆成功,jaas会回调LoginModule.commit()函数进行提交,可以在这里对用户进行授权。
  • 4.如果在授权阶段发生异常,jaas会调用LoginModule.abort()函数。
  • 5.调用LoginContext.logout()函数退出登陆。

5.相关的配置文件

jaas 有两个相关的配置文件,分别是 policy 文件和 config 文件。

policy 文件

  • 命名:xxx.policy
  • 使用方式:通过添加程序启动参数(前提,开启了securityManager),java -Djava.security.policy==xxx.policy
    policy 文件可以对代码和主体(Principal)进行授权配置,主要结构如下:
grant {

    ## 示例:permission xxx.Permission "name", "action";
    
    permission javax.security.auth.AuthPermission "doAsPrivileged";
    permission javax.security.auth.AuthPermission "doAs";
    permission javax.security.auth.AuthPermission "createLoginContext";
    permission java.util.PropertyPermission "os.name", "read";
    permission javax.security.auth.AuthPermission "modifyPrincipals";
};

grant principal com.fy.login.internal.SimplePrincipal "user" {
    permission java.util.PropertyPermission "user.*", "read";

};

有几个需要注意的点:

  • 1.policy文件有严格的格式限制,每个授权块后面必须有分号,每行后面也必须有分号
  • 2.如果没有 action,可省略 action 和 逗号,如果有,那么 name 后面必须加逗号。
  • 3.授权主体(Principal)的配置如上所述,语法结构为 grant principal xxx.Principal "name"{ 权限列表 };,这里的 principal 表示当前授权对象是个 Principal类,xxx.Principal表示自定义的Principal实现类,"user"表示当前授权主体的名称,该主体包含了一组权限。
  • 4.关于Principal需要特别说明的是:我们最好实现它的equals()hashCode()方法,并且在implies()方法中利用这两个方法来判断该subject是否蕴含该主体。

config 文件

  • 命名:xxx.config
  • 使用方式:通过添加程序启动参数(前提,开启了securityManager),java -Djava.security.auth.login.config=xxx.config

config 文件主要功能是指定通过new LoginContext(name)所对应name要使用的LoginModule类。例如,对ADMIN用户,我们可以配置AdminLoginModule类,进行更加严密的鉴权;而对USER用户,使用相对简单的鉴权。

config 文件示例:

user
{
    com.fy.login.internal.SimpleLoginModule required;
};

admin
{
    com.fy.login.internal.SimpleLoginModule required;
};

注:该有的分号不能省略。

二、实现自定义登陆模块

  • 通过 SPI 机制提供IUserService来实现密码获取和加载IValidateChain来进行更严格的鉴权。
  • EventListeners提供了静态的添加IEventListener的方法来添加登陆登出监听。
  • BaseMetadataNetMetadata用来保存用户信息。
  • 通过LoginManager.login(callback)传入的CallbackHandler来获取对应类型的Metadata信息。

注:该框架仅是用来熟悉jaas的。

参考地址:https://gitee.com/zolmk/x-login

标签:jaas,Java,框架,LoginModule,登陆,login,public,Principal
From: https://www.cnblogs.com/zolmk/p/16632340.html

相关文章

  • JavaScript 正则表达式
    JavaScript正则表达式|菜鸟教程 https://www.runoob.com/js/js-regexp.html正则表达式(英语:RegularExpression,在代码中常简写为regex、regexp或RE)使用单个字符串来描......
  • Java09-继承,抽象类
    第一章继承1.1概述由来多个类中存在相同属性和行为时,将这些内容抽取到单独一个类中,那么多个类无需再定义这些属性和行为,只要继承那一个类即可。如图所示:其中,多个类......
  • 【Java学习Day08】数据类型、变量及字节
    数据类型强类型语言要求变量的使用要严格符合规定,所有变量都必须先定义后才能使用弱类型语言要求变量的使用要符合规定,所有变量都必须先定义后才能使用Java......
  • IDEA工具插件之Java Visualizer
      打断点调试运行后后堆栈可视化效果: ......
  • JavaScript实现栈结构(Stack)
    Js实现栈结构一、前言1.1什么是数据结构数据结构就是在计算机中,存储和组织数据的方式。例如:图书管理,怎样摆放图书才能既能放很多书,也方便取?常见的数据结构:栈(Stack)......
  • JVisualVM监控远程Java进程
    一、添加远程IP地址选择“远程”,添加“远程主机“,填写IP地址,然后确定 二、使用JMX技术,修改Catalina.shJAVA_OPTS="$JAVA_OPTS-Dcom.sun.management.jmxremote-D......
  • Java学习-第一部分-第二阶段-第五节:集合
    集合笔记目录:(https://www.cnblogs.com/wenjie2000/p/16378441.html)前面我们保存多个数据使用的是数组,那么数组有不足的地方,我们分析一下。●数组长度开始时必须指定......
  • JavaBean属性赋值
    JavaBeanUtils工具类importlombok.experimental.UtilityClass;importlombok.extern.slf4j.Slf4j;importorg.springframework.beans.BeanUtils;importorg.springfr......
  • Django框架  快速查询目录
    Django框架 快速查询目录 django中前后端传输数据的编码格式(contentType)django中的中间件django中的cookie和sessiondjango中的csrf跨站请求伪造django中视图函数......
  • Java随机数的生成
    Random类生成一个[0,10)的随机整数Randomrandom=newRandom();intnum1=random.nextInt(10);生成一个[0,10]范围的随机整数[0,11)->[0,10]intnum2=random......