java的Jaas授权与鉴权
文章目录
- 1.概述
- 2. 概念预览
- 3.SecurityManager应用场景
- 2. 测试
- 2.1 无安全测试
- 2.2 安全测试
- 2.1 绑定授权策略文件
- 3. 其他java权限
- 4.优化
- 5.再次优化
- 错误集锦
- 1.1
- 1.2
1.概述
2. 概念预览
LoginContext
是javax.security.auth.login
包里的一个类,它描述了用于验证对象(subjects)
的方法。Subject
就是在某个你想去认证和分配访问权限的系统里的一个标识。一个主体(subject)可能是一个用户、一个进程或者是一台机器,它用javax.security.auth.Subject
类表示。由于一个Subject
可能涉及多个授权(一个网上银行密码和另一个电子邮件系统),java.security.Principal
就被用作在那些关联里的标识。也就是说,该Principal
接口是一个能够被用作代表某个实体、公司或者登陆ID的抽象概念。一个Subject
可能包含多个Principles.
Principal
:当一个Subject认证成功,Principal将会关联到这个Subject
。Principal表示Subject的身份表示
,必须要实现 java.security.Principal 和 java.io.Serializable 接口。Subject section 描述了更新Principal关联到subject的方法。- Credential :并不是主要的Jaas代码,任何类可以表示为Credential,并需要实现Credential的两个接口Refreshable和Destroyable。
3.SecurityManager应用场景
当运行未知的Java程序的时候,该程序可能有恶意代码(删除系统文件、重启系统等),为了防止运行恶意代码对系统产生影响,需要对运行的代码的权限进行控制,这时候就要启用Java安全管理器。
2. 测试
新建一个项目JavaJaasTest
,路径为:/Users/lcc/IdeaProjects/JavaJaasTest
2.1 无安全测试
public class App1 { public static void main(String[] args) { System.out.println(System.getProperty("java.home")); }
}
/Library/Java/JavaVirtualMachines/jdk1.8.0_131.jdk/Contents/Home/jre
2.2 安全测试
public class App2 {public static void main(String[] args) {//安装安全管理器System.setSecurityManager(new SecurityManager());System.out.println(System.getProperty("java.home"));}}
Exception in thread "main" java.security.AccessControlException: access denied ("java.util.PropertyPermission" "java.home" "read")at java.security.AccessControlContext.checkPermission(AccessControlContext.java:472)at java.security.AccessController.checkPermission(AccessController.java:884)at java.lang.SecurityManager.checkPermission(SecurityManager.java:549)at java.lang.SecurityManager.checkPropertyAccess(SecurityManager.java:1294)at java.lang.System.getProperty(System.java:717)at com.security.App2.main(App2.java:15)
2.1 绑定授权策略文件
grant {permission java.util.PropertyPermission "java.home", "read";
};
该授权的效果是任何用户运行的任何程序都有对java.home
的读权限,policy文件的具体格式请参看:
http://docs.oracle.com/javase/7/docs/technotes/guides/security/PolicyFiles.html
为安全管理器绑定policy文件的方式有两种:
- 在运行程序的时候加入
-Djava.security.policy=demo.policy
虚拟机启动参数; - 执行
System.setProperty(“java.security.policy”, “demo.policy”);
其实两者的效果一样,都是在设置系统属性,其中demo.policy
是路径,这里为了简单指定的是相对路径,绝对路径当然也没问题。再次运行程序不再抛出异常,说明程序拥有了对java.home系统属性的读取权限。
public class App3 {public static void main(String[] args) {System.setProperty("java.security.policy", "demo.policy");System.setProperty("java.security.policy", "/Users/lcc/IdeaProjects/JavaJaasTest/src/main/resources/demo.policy");//安装安全管理器System.setSecurityManager(new SecurityManager());System.out.println(System.getProperty("java.home"));}}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
这两种方法都是可以得到正确结果的。
3. 其他java权限
http://docs.oracle.com/javase/7/docs/technotes/guides/security/spec/security-spec.doc3.html#17001
java.security.AllPermission |
所有权限的集合 |
java.util.PropertyPermission |
系统/环境属性权限 |
java.lang.RuntimePermission |
运行时权限 |
java.net.SocketPermission |
Socket权限 |
java.io.FilePermission |
文件权限,包括读写,删除,执行 |
java.io.SerializablePermission |
序列化权限 |
java.lang.reflect.ReflectPermission |
反射权限 |
java.security.UnresolvedPermission |
未解析的权限 |
java.net.NetPermission |
网络权限 |
java.awt.AWTPermission |
AWT权限 |
java.sql.SQLPermission |
数据库sql权限 |
java.security.SecurityPermission |
安全控制方面的权限 |
java.util.logging.LoggingPermission |
日志控制权限 |
javax.net.ssl.SSLPermission |
安全连接权限 |
javax.security.auth.AuthPermission |
认证权限 |
javax.sound.sampled.AudioPermission |
音频系统资源的访问权限 |
4.优化
- LoginContext:认证核心类,也是入口类,用于触发登录认证,具体的登录模块由构造方法name参数指定
- LoginModule:登录模块,封装具体的登录认证逻辑,如果认证失败则抛出异常,成为则向Subject中添加一个Principal
- CallbackHandler:回调处理器,用于搜集认证信息
- Principal:代表程序用户的某一身份,与其密切相关的为Subject,用于代表程序用户,而一个用户可以多种身份,授权时可以针对某用户的多个身份分别授权
package com.security;import javax.security.auth.login.LoginContext;
import javax.security.auth.login.LoginException;/*** @Author: chuanchuan.lcc* @CreateDate: 2018/12/28 PM4:30* @Version: 1.0* @Description: java类作用描述:*/
public class App4 {public static void main(String[] args) {System.setProperty("java.security.auth.login.config", "/Users/lcc/IdeaProjects/JavaJaasTest/src/main/resources/demo.config");System.setProperty("java.security.policy", "/Users/lcc/IdeaProjects/JavaJaasTest/src/main/resources/demo.policy");System.setSecurityManager(new SecurityManager());try {//创建登录上下文LoginContext context = new LoginContext("demo", new DemoCallbackHander());//进行登录,登录不成功则系统退出context.login();} catch (LoginException le) {System.err.println("Cannot create LoginContext. " + le.getMessage());System.exit(-1);} catch (SecurityException se) {System.err.println("Cannot create LoginContext. " + se.getMessage());System.exit(-1);}//访问资源System.out.println(System.getProperty("java.home"));}
}
package com.security;import java.io.IOException;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;public class DemoCallbackHander implements CallbackHandler {@Overridepublic void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {NameCallback nameCallback = (NameCallback) callbacks[0];PasswordCallback passwordCallback = (PasswordCallback) callbacks[1];//设置用户名与密码nameCallback.setName(getUserFromSomeWhere());passwordCallback.setPassword(getPasswordFromSomeWhere().toCharArray());}//为简单起见用户名与密码写死直接返回,真实情况可以由用户输入等具体获取public String getUserFromSomeWhere() {return "zhangsan";}public String getPasswordFromSomeWhere() {return "zhangsan";}
}
package com.security;import java.io.IOException;
import java.security.Principal;
import java.util.Iterator;
import java.util.Map;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.FailedLoginException;
import javax.security.auth.login.LoginException;
import javax.security.auth.spi.LoginModule;public class DemoLoginModule implements LoginModule {private Subject subject;private CallbackHandler callbackHandler;private boolean success = false;private String user;private String password;public void initialize(Subject subject, CallbackHandler callbackHandler, Map<String, ?> sharedState, Map<String, ?> options) {this.subject = subject;this.callbackHandler = callbackHandler;}public boolean login() throws LoginException {NameCallback nameCallback = new NameCallback("请输入用户名");PasswordCallback passwordCallback = new PasswordCallback("请输入密码", false);Callback[] callbacks = new Callback[]{nameCallback, passwordCallback};try {//执行回调,回调过程中获取用户名与密码callbackHandler.handle(callbacks);//得到用户名与密码user = nameCallback.getName();password = new String(passwordCallback.getPassword());} catch (IOException | UnsupportedCallbackException e) {success = false;throw new FailedLoginException("用户名或密码获取失败");}//为简单起见认证条件写死if(user.length()>3 && password.length()>3) {success = true;//认证成功}return true;}public boolean commit() throws LoginException {if(!success) {return false;} else {//如果认证成功则得subject中添加一个Principal对象//这样某身份用户就认证通过并登录了该应用,即表明了谁在执行该程序this.subject.getPrincipals().add(new DemoPrincipal(user));return true;}}public boolean abort() throws LoginException {logout();return true;}public boolean logout() throws LoginException {//退出时将相应的Principal对象从subject中移除Iterator<Principal> iter = subject.getPrincipals().iterator();while(iter.hasNext()) {Principal principal = iter.next();if(principal instanceof DemoPrincipal) {if(principal.getName().equals(user)) {iter.remove();break;}}}return true;}}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
package com.security;import java.security.Principal;public class DemoPrincipal implements Principal {private String name;public DemoPrincipal(String name) {this.name = name;}@Overridepublic String getName() {return this.name;}}
/Users/lcc/IdeaProjects/JavaJaasTest/src/main/resources/demo.config
demo {com.security.DemoLoginModule required debug=true;
};
/Users/lcc/IdeaProjects/JavaJaasTest/src/main/resources/demo.policy
grant {permission javax.security.auth.AuthPermission "createLoginContext.demo";permission javax.security.auth.AuthPermission "modifyPrincipals";permission java.util.PropertyPermission "java.home", "read";
};
5.再次优化
package com.security;import javax.security.auth.Subject;
import javax.security.auth.login.LoginContext;
import javax.security.auth.login.LoginException;
import java.security.Principal;
import java.security.PrivilegedAction;/*** @Author: chuanchuan.lcc* @CreateDate: 2018/12/28 PM4:47* @Version: 1.0* @Description: java类作用描述:*/
public class App5 {public static void main(String[] args) {System.setProperty("java.security.auth.login.config", "/Users/lcc/IdeaProjects/JavaJaasTest/src/main/resources/demo5.config");System.setProperty("java.security.policy", "/Users/lcc/IdeaProjects/JavaJaasTest/src/main/resources/demo5.policy");System.setSecurityManager(new SecurityManager());LoginContext context = null;try {//创建登录上下文context = new LoginContext("Demo", new DemoCallbackHander());//进行登录,登录不成功则系统退出context.login();} catch (LoginException le) {System.err.println("Cannot create LoginContext. " + le.getMessage());System.exit(-1);} catch (SecurityException se) {System.err.println("Cannot create LoginContext. " + se.getMessage());System.exit(-1);}//访问资源Subject subject = context.getSubject();System.out.println(subject);for (Principal principal : subject.getPrincipals()) {System.out.println("\t" + principal.toString());}DemoPrivilegedAction demoPrivilegedAction = new DemoPrivilegedAction();//该方法调用需要"doAsPrivileged"权限Subject.doAsPrivileged(subject, new PrivilegedAction<Object>() {@Overridepublic Object run() {System.out.println(System.getProperty("java.home"));return null;}}, null);}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 当初始化时,
LoginContext
对象首先在JAAS配置文件中找到myperson
项,然后更具该项的内容决定该加载哪个LoginModule
对象。 - 在登录时,
LoginContext
对象调用每个LoginModule
对象的login()
方
法。 - 每个
login()
方法进行验证操作或获得一个CallbackHandle
对象。 CallbackHandle
对象通过使用一个或多个CallBack
方法同用户进行交互
,获得用户输入。- 向一个
新的Subject对象
中填入验证信息
。
# 路径 /Users/lcc/IdeaProjects/JavaJaasTest/src/main/resources/demo5.configDemo {com.security.DemoLoginModule required debug=true;
};
# 路径 /Users/lcc/IdeaProjects/JavaJaasTest/src/main/resources/demo5.policygrant {permission javax.security.auth.AuthPermission "createLoginContext.Demo";permission javax.security.auth.AuthPermission "modifyPrincipals";permission javax.security.auth.AuthPermission "doAsPrivileged";
};
// JAAS 授权,授权给指定的用户或身份
grant Principal com.security.DemoPrincipal "zhangsan" {permission java.util.PropertyPermission "java.home", "read";
};
Exception in thread "main" java.security.AccessControlException: access denied ("java.util.PropertyPermission" "java.home" "read")at java.security.AccessControlContext.checkPermission(AccessControlContext.java:472)at java.security.AccessController.checkPermission(AccessController.java:884)at java.lang.SecurityManager.checkPermission(SecurityManager.java:549)at java.lang.SecurityManager.checkPropertyAccess(SecurityManager.java:1294)at java.lang.System.getProperty(System.java:717)at com.security.App5$1.run(App5.java:46)at java.security.AccessController.doPrivileged(Native Method)at javax.security.auth.Subject.doAsPrivileged(Subject.java:483)at com.security.App5.main(App5.java:43)
这个原因是因为com.security.DemoPrincipal
需要覆写·equals
和 hashCode
方法,修改类
package com.security;import java.security.Principal;public class DemoPrincipal implements Principal {private String name;public DemoPrincipal(String name) {this.name = name;}@Overridepublic String getName() {return this.name;}public boolean equals(Object o) {if (o == null)return false;if (this == o)return true;if (!(o instanceof DemoPrincipal))return false;DemoPrincipal that = (DemoPrincipal) o;if (this.getName().equals(that.getName()))return true;return false;}public int hashCode() {return name.hashCode();}@Overridepublic String toString() {return "DemoPrincipal{" +"name='" + name + '\'' +'}';}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
主体: 主用户: DemoPrincipal{name='zhangsan'}DemoPrincipal{name='zhangsan'}
/Library/Java/JavaVirtualMachines/jdk1.8.0_131.jdk/Contents/Home/jre
错误集锦
1.1
Cannot create LoginContext. access denied ("javax.security.auth.AuthPermission" "createLoginContext.myperson")
1.2
javax.security.auth.login.LoginException: 没有为CountFiles配置 LoginModules
java的Jaas授权与鉴权相关推荐
- 【java】java的Jaas授权与鉴权
文章目录 1.概述 2. 概念预览 3.SecurityManager应用场景 2. 测试 2.1 无安全测试 2.2 安全测试 2.1 绑定授权策略文件 3. 其他java权限 4.优化 5.再次优 ...
- 【安全】java的Jaas授权与鉴权
文章目录 1.概述 2. 概念预览 2.1 文件格式 2.2 LoginModule 2.3 flag 2.4 options 2.5 使用 3.SecurityManager应用场景 2. 测试 2 ...
- 【Spring Cloud Alibaba 实战 | 总结篇】Spring Cloud Gateway + Spring Security OAuth2 + JWT 实现微服务统一认证授权和鉴权
一. 前言 hi,大家好~ 好久没更文了,期间主要致力于项目的功能升级和问题修复中,经过一年时间这里只贴出关键部分代码的打磨,[有来]终于迎来v2.0版本,相较于v1.x版本主要完善了OAuth2认证 ...
- 认证、授权、鉴权、权限控制
目录 0x01 概念 0x02 前端-后端授权/鉴权方案 2.1 Http Basic Authentication 2.2 session-cookie 2.3 token 2.4 JWT(Json ...
- [Asp.Net Core]鉴权授权
鉴权授权 为了拦截一些操作: 传统的授权方式:session/Cookies来完成: 1.在请求某个Action之前去做校验,验证当前操作者是否登录过,登录过就有权限 2.如果没有权限就跳转到登录页中 ...
- 钉钉企业内部应用授权免登+鉴权
一.创建应用 在钉钉管理后台-应用开发-企业内部开发-创建应用(我们这边创建的是H5微应用) 创建好了之后,会拿到应用凭证:AgentId,AppKey,AppSecret 这三个值在开发中会用到 二 ...
- 注册登录鉴权以及购物车常见管理
这里写自定义目录标题 注册鉴权以及购物车系统相关知识点 对称加密和非对称加密: **jwt**包含三部分: **登录**分为**授权和鉴权** 注册鉴权以及购物车系统相关知识点 ** 对称加密和非对称 ...
- 请求令牌 接口_时序图说明JWT用户认证及接口鉴权的细节
JWT用户认证及接口鉴权的细节以及原理 一.回顾JWT的授权及鉴权流程 在笔者的上一篇文章中,已经为大家介绍了JWT以及其结构及使用方法.其授权与鉴权流程浓缩为以下两句话: 授权:使用可信用户信息(用 ...
- dispatch作用 react_「React系列」手把手带你撸后台系统(Redux与路由鉴权)
[React系列]手把手带你撸后台系统(Redux与路由鉴权) 来源:https://juejin.im/post/5d9b5ddee51d45781b63b8f7 上一篇我们介绍了系统架构,这一篇将 ...
- 开放平台中的鉴权的实现
转载请注明:http://blog.csdn.net/HEL_WOR/article/details/51660979 在描述鉴权和流控之前,可能需要先描述为什么需要搭建开放平台. 开放平台最先由FB ...
最新文章
- lstm timestep一般是多少_用LSTM中的不同时间步长预测使用keras
- 【转载】Linux修改文件权限
- 21天舞动西浦报名失败的教训:先下手为强
- Visual Studio 字体抗锯齿插件 Text Sharp
- git gui管理服务器配置文件,从 Git Gui 管理的Repository(库) 提交更改到 Bonobo服务器管理的Repository(库)...
- Linux Ubuntu16.04界面美化
- python3 虚拟环境 pip 版本_【python知识】 - Python3之PIPENV虚拟环境及封装
- 教你怎么使用Jmail发送匿名的邮件(不要身份认证)
- 高并发编程-07-JDK提供的原子类操作及原理
- C/C++ —— signed 与 unsigned 有符号和无符号数及其移位
- grafana zabbix 模板_【Grafana教程】安装Grafana并配置Zabbix数据源
- 项目进度管理-活动历时估算工具技术:三点估算
- 【教程】 如何在linux/mac下安装pascal
- Android图片转化黑白图片,图像二值化,生成图像二值化后的黑白图像和图像矩阵(无压缩0,1矩阵),可灵活设置二值化值域
- 路由器 刷rom php,路由器刷固件常用命令Openwrt 之mtd/mtd_write烧写固件
- Hub设备、网桥、二层交换机设备概述
- LeetCode 5855. 找出数组中的第 K 大整数(自定义排序函数)
- 易观CTO郭炜:开源,不是天才的甜点,而是勤奋者的盛宴
- 多态的实现机制是什么?
- java.sql.SQLException: The server time zone value‘xxxxxxxx‘ is unrecognized
热门文章
- unity 地图画格_[蛮牛译馆]UnityC#教程—六边形地图系列之创建网格(中)
- 西瓜播放器xgplayer的简单使用demo
- 用Wineskin在Mac上运行exe文件
- DirectX修复工具(DirectX Repair)是一款系统级工具软件,简便易用。本程序为绿色版,无需安装,可直接运行。 本程序的主要功能是检测当前系统的DirectX状态,如果发现异常
- 在线json解析工具 在线js解析加密混合工具
- jieba java_【NLP】【一】中文分词之jieba
- Web服务器性能压力测试工具
- 记录一下Android 长截屏功能
- axure rp10安装教程,axurerp10安装步骤
- 西门子s300编程实例_数控车床加工编程典型实例分析(西门子802S数控系统编程教学)...