- 浏览: 115691 次
- 性别:
- 来自: 北京
文章分类
最新评论
-
honey_fansy:
能讲讲为什么要用final修饰吗?还是说不一定?我看了好几段代 ...
关于ThreadLocal的内存泄露 -
heipacker:
czpsailer 写道为啥这么多人投隐藏,如果LZ那里说的不 ...
关于ThreadLocal的内存泄露 -
r361251:
不懂,貌似好高级的样子。
机器学习常用方法 -
yangyi:
jackyin5918 写道个人认为, 内部的ThreadLo ...
关于ThreadLocal的内存泄露 -
jackyin5918:
yangyi 写道jackyin5918 写道C_J 写道- ...
关于ThreadLocal的内存泄露
这篇随笔谈一谈如何在Java环境下利用Unix/Linux的用户名和密码对用户的权限作出过滤。为方便大家学习交流,本文中给出了源代码,借此抛砖引玉,欢迎大家对这个简单的登录模型做出改进或者设计出自己的技术方案。
由标题我们不难看出,与本文相关的知识点主要有3个:
1 JAAS这个解耦设计的多层验证方法(1.4后已归入Java核心库中)
2 应用JNI访问底层代码,及JNI中简单的类型匹配
3 在shadow模式下,Unix/Linux系统的用户验证
首先聊聊JAAS,顾名思义,JAAS由认证和授权两个主要组件组成。JAAS的交互点在LoginContext这个类里面,在构造LoginContext时,常常需要指定两个内容(还有其他默认的构造子重载形式),这两个内容是LoginModule的名字和Subject。
为使描述直观,先给出代码如下:
先说LoginModule的名字,在系统属性java.security.auth.login.config中(或者在jre/lib/security/java.security)指定了LoginModule的配置文件,LoginModule在Java中被定义成一个接口,这个地方应用了面向对象的依赖倒置原则,使用了类似JDBC这样的SPI的机制来定制认证策略。根据用户在构造LoginContext时指定的LoginModule的名字Java在系统环境中找到对应的LoginModule配置文件,这个配置文件的最简单形式如下:
mylogin {
UnixLoginModule required
};
这时当我们应用mylogin这个名字实例化LoginContext的时候,系统就会自动的找到UnixLoginModule这个LoginModule去处理。后面的required是一个flag标志,表示此次验证的关键性,有4个值可以选择,当选定required时则表示必须成功,由此我们就可以定义一系列的验证,形成一个过滤层,并根据不同的flag得出最后的结论,比如:我们可能希望我们的web用户只要通过数据库的验证,而不必通过操作系统的验证。
此外我们还可以设置一些其他的参数(以key=value的形式),而且实际上验证是两阶段提交的,并且可以通过回调函数的形式在具体的认证平台上做一些个性化Context设置。对这些JAAS细节感兴趣的朋友可以读相应的JAAS文档规范。
再说第二个参数Subject,这个主题封装了用户需要验证的信息,主要包括principal和公钥私钥两部分,详细的设置方法可以参考上面的代码。
lc.login返回了一个true或false表示了这次的验证是否成功。
当一个Subject成功login后,就可以通过这个Subject做一些特许的动作Subject.doAs,这些动作根据Subject中principal的不同在com.sun.security.auth.PolicyFile指定的配置文件做了定义,这部分是属于JAAS授权的内容,因为在我们的程序中暂时用不到,所以不做详细讨论了,我们仅仅根据login返回的true或false来决定用户是否可以登录我们的系统即可。
OK,说到这里,我们给出UnixLoginModule的实现代码:
代码中的各个方法是LoginModule所定义的必须实现的方法。注意到代码中,我们应用了PasswdCheck.check(this.usr, this.passwd)来做最后的验证,这是因为对Unix系统用户的验证必须调用系统API才可以,而系统API是以C的形式提供的,因此我们需要借助JNI。现在我们看看PasswdCheck这个类:
在这里用到了JNI来调用底层的用户名密码验证方案,为此我们需要构造出libpasswd.so这个库。
一步一步来:
1 用javah生成JNI的头文件:
javah PasswdCheck
得到如下代码:
现在把头文件中定义的函数实现:
在jni.h这个头文件中定义了jni和c之间的类型关系,通过分析,用户名密码的字符串可以通过如下函数获取:
char * username =(*env)->GetStringUTFChars(env, usr, NULL);
char * password =(*env)->GetStringUTFChars(env, psw, NULL);
其他的简单型别很多被直接typedef了。
我们真对生成的头文件,实现如下:
上面的实现中的结构体spwd定义如下:
getspnam函数可以获取一个被单向加密后的密码(有4种可选加密形式)
crypt函数把我们的原始密码按相同密钥和算法加密后,即可通过比较加密后字符串的形式获取是否密码正确的信息。需要主义的是只有在使用shadow机制的系统中才应用getspnam,如果/etc/passwd直接描述了密码,则可以通过函数getpwnam来获取(或者直接解析文本),这时一般采用的是13位的DES加密,问题变得简单。
在编写完实现后通过命令
gcc -lcrypt PasswdCheck.c -shared -o libpasswd.so
进行编译,把这个库cp到/usr/lib(或其他ld_library_path)下就可以用平台相关的方式System.loadLibrary加载,否则就要用系统绝对路径名了(利用System.load)
因为只有root能获取到getspnam,所以我们只能这样来执行我们的java进行验证,sudo java MyLogin (yiyang is in group wheel defined in /etc/sudoers)
否则将得到如下出错信息:
当然,如果我们不用JNI,而采用Web Services(具体方法见笔者上一篇blog: http://yangyi.blogjava.net)那么可以通过set suid的形式定制一个进程了(不过这已经是另一个话题),毕竟用root启动tomcat不是很让人放心:
chown root XXX
chmod +s XXX
Anyway, 至此通过JAAS认证Unix用户的基本思路就描述完了,读者可以填补其中的漏洞并把JAAS用到自己的工作场景中。
由标题我们不难看出,与本文相关的知识点主要有3个:
1 JAAS这个解耦设计的多层验证方法(1.4后已归入Java核心库中)
2 应用JNI访问底层代码,及JNI中简单的类型匹配
3 在shadow模式下,Unix/Linux系统的用户验证
首先聊聊JAAS,顾名思义,JAAS由认证和授权两个主要组件组成。JAAS的交互点在LoginContext这个类里面,在构造LoginContext时,常常需要指定两个内容(还有其他默认的构造子重载形式),这两个内容是LoginModule的名字和Subject。
为使描述直观,先给出代码如下:
<!---->import java.security.Principal;
import javax.security.auth.Subject;
import javax.security.auth.login.LoginContext;
import javax.security.auth.login.LoginException;
public class MyLogin {
public MyLogin(){
Subject subject = new Subject();
subject.getPrincipals().add(new Principal(){
public String getName() {
return "yiyang";
}
});
subject.getPrivateCredentials().add("sh0w00f");
try {
LoginContext lc = new LoginContext("mylogin",subject);
lc.login();
} catch (LoginException e) {
e.printStackTrace();
}
}
public static void main(String[] args){
new MyLogin();
}
}
import javax.security.auth.Subject;
import javax.security.auth.login.LoginContext;
import javax.security.auth.login.LoginException;
public class MyLogin {
public MyLogin(){
Subject subject = new Subject();
subject.getPrincipals().add(new Principal(){
public String getName() {
return "yiyang";
}
});
subject.getPrivateCredentials().add("sh0w00f");
try {
LoginContext lc = new LoginContext("mylogin",subject);
lc.login();
} catch (LoginException e) {
e.printStackTrace();
}
}
public static void main(String[] args){
new MyLogin();
}
}
先说LoginModule的名字,在系统属性java.security.auth.login.config中(或者在jre/lib/security/java.security)指定了LoginModule的配置文件,LoginModule在Java中被定义成一个接口,这个地方应用了面向对象的依赖倒置原则,使用了类似JDBC这样的SPI的机制来定制认证策略。根据用户在构造LoginContext时指定的LoginModule的名字Java在系统环境中找到对应的LoginModule配置文件,这个配置文件的最简单形式如下:
mylogin {
UnixLoginModule required
};
这时当我们应用mylogin这个名字实例化LoginContext的时候,系统就会自动的找到UnixLoginModule这个LoginModule去处理。后面的required是一个flag标志,表示此次验证的关键性,有4个值可以选择,当选定required时则表示必须成功,由此我们就可以定义一系列的验证,形成一个过滤层,并根据不同的flag得出最后的结论,比如:我们可能希望我们的web用户只要通过数据库的验证,而不必通过操作系统的验证。
此外我们还可以设置一些其他的参数(以key=value的形式),而且实际上验证是两阶段提交的,并且可以通过回调函数的形式在具体的认证平台上做一些个性化Context设置。对这些JAAS细节感兴趣的朋友可以读相应的JAAS文档规范。
再说第二个参数Subject,这个主题封装了用户需要验证的信息,主要包括principal和公钥私钥两部分,详细的设置方法可以参考上面的代码。
lc.login返回了一个true或false表示了这次的验证是否成功。
当一个Subject成功login后,就可以通过这个Subject做一些特许的动作Subject.doAs,这些动作根据Subject中principal的不同在com.sun.security.auth.PolicyFile指定的配置文件做了定义,这部分是属于JAAS授权的内容,因为在我们的程序中暂时用不到,所以不做详细讨论了,我们仅仅根据login返回的true或false来决定用户是否可以登录我们的系统即可。
OK,说到这里,我们给出UnixLoginModule的实现代码:
<!---->import java.util.Map;
import javax.security.auth.Subject;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.login.LoginException;
import javax.security.auth.spi.LoginModule;
public class UnixLoginModule implements LoginModule {
private String usr, passwd;
public boolean abort() throws LoginException {
return false;
}
public boolean commit() throws LoginException {
System.out.println("Passing final confirmation\ndone");
return true;
}
public boolean login() throws LoginException {
;
if (PasswdCheck.check(this.usr, this.passwd) == 0) {
System.out.println("Your Login Succeed");
return true;
}
System.out.println("Your Login failed");
return false;
}
public boolean logout() throws LoginException {
return false;
}
public void initialize(Subject subject, CallbackHandler callbackHandler,
Map<String, ?> sharedState, Map<String, ?> options) {
this.passwd = (String) subject.getPrivateCredentials().iterator()
.next();
this.usr = (String) subject.getPrincipals().iterator().next().getName();
}
}
import javax.security.auth.Subject;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.login.LoginException;
import javax.security.auth.spi.LoginModule;
public class UnixLoginModule implements LoginModule {
private String usr, passwd;
public boolean abort() throws LoginException {
return false;
}
public boolean commit() throws LoginException {
System.out.println("Passing final confirmation\ndone");
return true;
}
public boolean login() throws LoginException {
;
if (PasswdCheck.check(this.usr, this.passwd) == 0) {
System.out.println("Your Login Succeed");
return true;
}
System.out.println("Your Login failed");
return false;
}
public boolean logout() throws LoginException {
return false;
}
public void initialize(Subject subject, CallbackHandler callbackHandler,
Map<String, ?> sharedState, Map<String, ?> options) {
this.passwd = (String) subject.getPrivateCredentials().iterator()
.next();
this.usr = (String) subject.getPrincipals().iterator().next().getName();
}
}
代码中的各个方法是LoginModule所定义的必须实现的方法。注意到代码中,我们应用了PasswdCheck.check(this.usr, this.passwd)来做最后的验证,这是因为对Unix系统用户的验证必须调用系统API才可以,而系统API是以C的形式提供的,因此我们需要借助JNI。现在我们看看PasswdCheck这个类:
<!---->public class PasswdCheck {
static{
System.out.println(System.getProperty("java.library.path"));
Runtime.getRuntime().load("/home/yiyang/eclipse/workspace/JAAS/libpasswd.so");
}
public native static int check(String usr, String passwd);
}
static{
System.out.println(System.getProperty("java.library.path"));
Runtime.getRuntime().load("/home/yiyang/eclipse/workspace/JAAS/libpasswd.so");
}
public native static int check(String usr, String passwd);
}
在这里用到了JNI来调用底层的用户名密码验证方案,为此我们需要构造出libpasswd.so这个库。
一步一步来:
1 用javah生成JNI的头文件:
javah PasswdCheck
得到如下代码:
<!---->/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class PasswdCheck */
#ifndef _Included_PasswdCheck
#define _Included_PasswdCheck
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: PasswdCheck
* Method: check
* Signature: (Ljava/lang/String;Ljava/lang/String;)I
*/
JNIEXPORT jint JNICALL Java_PasswdCheck_check
(JNIEnv *, jclass, jstring, jstring);
#ifdef __cplusplus
}
#endif
#endif
#include <jni.h>
/* Header for class PasswdCheck */
#ifndef _Included_PasswdCheck
#define _Included_PasswdCheck
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: PasswdCheck
* Method: check
* Signature: (Ljava/lang/String;Ljava/lang/String;)I
*/
JNIEXPORT jint JNICALL Java_PasswdCheck_check
(JNIEnv *, jclass, jstring, jstring);
#ifdef __cplusplus
}
#endif
#endif
现在把头文件中定义的函数实现:
在jni.h这个头文件中定义了jni和c之间的类型关系,通过分析,用户名密码的字符串可以通过如下函数获取:
char * username =(*env)->GetStringUTFChars(env, usr, NULL);
char * password =(*env)->GetStringUTFChars(env, psw, NULL);
其他的简单型别很多被直接typedef了。
我们真对生成的头文件,实现如下:
<!---->#include "PasswdCheck.h"//生成的头文件
#include "pwd.h"//getspnam
#include "stdio.h"
#include "unistd.h"//crypt必需
#include "shadow.h"//getspnam
#define _XOPEN_SOURCE//crypt必需
JNIEXPORT jint JNICALL Java_PasswdCheck_check
(JNIEnv * env, jclass jc, jstring usr, jstring psw){
char * username =(*env)->GetStringUTFChars(env, usr, NULL);
char * password =(*env)->GetStringUTFChars(env, psw, NULL);
struct spwd * sp = getspnam(username);
char* p;
p = crypt(password, sp->sp_pwdp);
return strcmp(sp->sp_pwdp,p);
}
#include "pwd.h"//getspnam
#include "stdio.h"
#include "unistd.h"//crypt必需
#include "shadow.h"//getspnam
#define _XOPEN_SOURCE//crypt必需
JNIEXPORT jint JNICALL Java_PasswdCheck_check
(JNIEnv * env, jclass jc, jstring usr, jstring psw){
char * username =(*env)->GetStringUTFChars(env, usr, NULL);
char * password =(*env)->GetStringUTFChars(env, psw, NULL);
struct spwd * sp = getspnam(username);
char* p;
p = crypt(password, sp->sp_pwdp);
return strcmp(sp->sp_pwdp,p);
}
上面的实现中的结构体spwd定义如下:
<!---->struct spwd {
char *sp_namp; /* user login name */
char *sp_pwdp; /* encrypted password */
long int sp_lstchg; /* last password change */
long int sp_min; /* days until change allowed. */
long int sp_max; /* days before change required */
long int sp_warn; /* days warning for expiration */
long int sp_inact; /* days before account inactive */
long int sp_expire; /* date when account expires */
unsigned long int sp_flag; /* reserved for future use */
}
char *sp_namp; /* user login name */
char *sp_pwdp; /* encrypted password */
long int sp_lstchg; /* last password change */
long int sp_min; /* days until change allowed. */
long int sp_max; /* days before change required */
long int sp_warn; /* days warning for expiration */
long int sp_inact; /* days before account inactive */
long int sp_expire; /* date when account expires */
unsigned long int sp_flag; /* reserved for future use */
}
getspnam函数可以获取一个被单向加密后的密码(有4种可选加密形式)
crypt函数把我们的原始密码按相同密钥和算法加密后,即可通过比较加密后字符串的形式获取是否密码正确的信息。需要主义的是只有在使用shadow机制的系统中才应用getspnam,如果/etc/passwd直接描述了密码,则可以通过函数getpwnam来获取(或者直接解析文本),这时一般采用的是13位的DES加密,问题变得简单。
在编写完实现后通过命令
gcc -lcrypt PasswdCheck.c -shared -o libpasswd.so
进行编译,把这个库cp到/usr/lib(或其他ld_library_path)下就可以用平台相关的方式System.loadLibrary加载,否则就要用系统绝对路径名了(利用System.load)
因为只有root能获取到getspnam,所以我们只能这样来执行我们的java进行验证,sudo java MyLogin (yiyang is in group wheel defined in /etc/sudoers)
否则将得到如下出错信息:
<!---->#
# An unexpected error has been detected by Java Runtime Environment:
#
# SIGSEGV (0xb) at pc=0xb7ef95ad, pid=9726, tid=3084450720
#
# Java VM: Java HotSpot(TM) Client VM (1.6.0_03-b05 mixed mode)
# Problematic frame:
# C [libpasswd.so+0x5ad] Java_PasswdCheck_check+0x61
#
# An error report file with more information is saved as hs_err_pid9726.log
#
# If you would like to submit a bug report, please visit:
# http://java.sun.com/webapps/bugreport/crash.jsp
#
# An unexpected error has been detected by Java Runtime Environment:
#
# SIGSEGV (0xb) at pc=0xb7ef95ad, pid=9726, tid=3084450720
#
# Java VM: Java HotSpot(TM) Client VM (1.6.0_03-b05 mixed mode)
# Problematic frame:
# C [libpasswd.so+0x5ad] Java_PasswdCheck_check+0x61
#
# An error report file with more information is saved as hs_err_pid9726.log
#
# If you would like to submit a bug report, please visit:
# http://java.sun.com/webapps/bugreport/crash.jsp
#
当然,如果我们不用JNI,而采用Web Services(具体方法见笔者上一篇blog: http://yangyi.blogjava.net)那么可以通过set suid的形式定制一个进程了(不过这已经是另一个话题),毕竟用root启动tomcat不是很让人放心:
chown root XXX
chmod +s XXX
Anyway, 至此通过JAAS认证Unix用户的基本思路就描述完了,读者可以填补其中的漏洞并把JAAS用到自己的工作场景中。
发表评论
-
profiling java applications with jvisualvm
2011-09-29 18:52 10061) Open jvisualvm, which is bun ... -
static import
2011-05-22 10:51 1835Static import支持略去类型名的public sta ... -
JPA的一些知识(Entity)
2011-05-21 22:54 4292何为Entity Java EE规范中 ... -
关于Java中的编码
2011-04-26 17:30 1004编码转换,实际就是把byte数组转换为char数组的过程,或者 ... -
commons-net FTPClient API存取设计
2010-07-07 22:51 1683文件系统无非就是文件的存取和组织结构。 访问一个文件系统的AP ... -
Spring Security 2 中动态角色实现的讨论
2009-03-04 13:04 1465安全框架的主体包括两 ... -
富客户端技术中的JavaScript脚本国际化
2008-12-24 13:31 1227当前的富客户端可以包 ... -
windows中不能双击打开jar文件的解决办法
2008-12-22 18:23 2983看此文前请保证jar包中有至少一个Main方法入口,及图形化的 ... -
JSON通用服务端处理
2008-11-24 18:18 2022最近在学习JavaScript,发现不论是ext还是proto ... -
[译]JDBC4.0具有哪些新特性?
2007-04-24 16:25 1429http://www.blogjava.net/yangyi/ ... -
myeclipse
2007-12-28 11:39 1296刚看了myeclipse,eclipse是一个很可怕的东西,它 ... -
如何实现包含插件功能的Applet Web界面
2008-01-02 15:07 1580不知诸位有没有想过用Applet来组织Web的程序界面?小弟最 ... -
如何学习spring
2008-01-16 10:19 2125学习这些框架技术,我觉得归根结底就是做什么的,为什么做,如何做 ... -
延迟加载技术及其在iBATIS中的实现
2007-12-09 19:56 1586O/R映射框架的延迟加载技术实现大体上有这么4种(参看Mart ... -
浅谈Java中的通信机制及与C/C++ API的集成
2007-12-06 21:05 2769背景: 对于旧有系统的 ... -
Apache commons-Email中文问题的解决办法
2006-12-12 19:15 2397Apache commons-email是对javamailA ... -
如何应用Hibernate在运行期获取属性的值
2006-12-12 19:11 1241java 代码 import java.lan ... -
如何用java做数组乱序?
2006-12-12 19:10 4787前些天用java做了一个数组乱序,首先建立快速排序算法,排序的 ... -
Spring Ioc值得注意的两个特性
2006-12-12 19:07 15921 Spring支持生命周期的回调,通过在bean配置属性中增 ... -
数字验证码小图生成程序
2006-12-12 18:44 1586做了一个登陆验证码的生成小程序,或许对大家有用。支持背景图和文 ...
相关推荐
Java Authentication and Authorization Service (JAAS) 是Java平台中用于实现用户身份验证和权限管理的核心组件。这个"Java JAAS安全认证 demo"是一个示例项目,旨在帮助开发者理解如何在Java应用中实施安全认证...
JAAS提供了一种标准的方式来实现这一目标,允许开发者在不深入了解底层安全机制的情况下,构建安全的应用程序。 **JAAS 登录验证机制** JAAS的核心概念是登录模块(LoginModule),它是处理用户身份验证逻辑的组件...
Java 2平台的安全框架主要关注代码来源的认证和控制,而JAAS则在此基础上增加了对代码执行者的认证和授权,从而实现了更加精细的访问控制。 随着互联网安全问题的日益凸显,JAAS作为一种强大的安全机制,在Java EE ...
### 在JAAS基础上的Java安全编程 #### 一、引言 随着互联网技术的发展和企业对数据安全的重视,Java作为一种广泛应用的编程语言,在安全领域扮演着越来越重要的角色。JAAS(Java Authentication and Authorization...
Java Authentication and Authorization Service (JAAS) 是Java平台中用于安全性的核心组件,它为开发者提供了一种机制来处理用户身份验证和权限控制。这个服务允许应用程序执行基于角色的安全性,这意味着用户的...
Java Authentication and Authorization Service (JAAS) 是Java平台中用于实现用户认证和权限授权的一个核心组件。它为开发者提供了一种灵活的方式来实现安全控制,确保只有经过验证和授权的用户能够访问敏感资源或...
3. **配置JAAS配置文件**:在Mac系统中,JAAS配置文件通常位于`/Library/Java/JavaVirtualMachines/jdk版本.jdk/Contents/Home/lib/security/java.policy`。你需要在这个文件中添加你的应用程序和LoginModule的配置...
Java Authentication and Authorization Service (JAAS) 是 Java 平台中用于安全管理的重要组件,它提供了一种框架,使得应用程序可以进行用户身份验证和权限控制。在本文中,我们将深入探讨 JAAS 的核心概念、工作...
### 利用JAAS实现简单的页面验证与授权 #### JAAS简介 Java Authentication and Authorization Service (JAAS) 是 Java 平台提供的一种安全框架,它主要用于实现应用级别的身份验证和授权服务。JAAS 的出现是对 ...
Java Authentication and Authorization Service (JAAS) 是Java平台中用于安全性的关键组件,它提供了一种框架,用于在Java应用程序中实现认证(Authentication)和授权(Authorization)。`jaas.jar` 文件是这个...
Java Authentication and Authorization Service (JAAS) 是Java平台中用于安全性的关键组件,它提供了一种框架,使得应用程序能够实现用户身份验证和权限管理。在这个教程中,我们将深入探讨JAAS的核心概念、工作...
_Jaas_Kerber_jaas_KERBEROS_kerberos_Java_login.a"压缩包文件包含了关于如何在Java环境中使用JAAS实现Kerberos登录和委托的示例代码。Kerberos是一种广泛使用的网络身份验证协议,它提供了强大的安全性,通过一次...
Java Authentication and Authorization Service (JAAS) 是Java平台中用于安全验证和权限管理的重要框架。它为应用程序提供了一种标准化的方式来处理用户身份验证和权限分配,从而确保只有经过验证的用户才能访问受...
在Java中,我们可以使用`KerberosLoginModule`实现Kerberos认证。这个模块是Java的登录框架(JAAS,Java Authentication and Authorization Service)的一部分,允许用户根据策略文件配置认证流程。 - **配置JAAS...
Java Authentication and Authorization Service (JAAS) 是Java平台提供的一种安全框架,用于实现用户身份验证和权限管理。这个框架使得开发者可以轻松地在Java应用程序中集成安全性,而不必深入理解底层的复杂安全...
Java Authentication and Authorization Service (JAAS) 是Java平台上用于管理和实施安全策略的重要组件,它提供了一种灵活且可...对于任何需要在Java环境中实现安全功能的开发者而言,理解和掌握JAAS都是至关重要的。
JAAS(Java Authentication and Authorization Service)是Java平台提供的一种安全框架,用于实现客户端应用程序的安全认证和授权管理。它为Java应用提供了一种灵活的方式来实现安全控制,使得开发人员能够轻松地在...
### JAAS:灵活的Java安全机制 #### 一、引言 Java Authentication and Authorization Service (JAAS, Java验证和授权API)为Java应用程序提供了一种扩展标准Java 2安全模型的方法。通过添加验证主题(即用户或其他...
4. **过滤器与拦截器**:为了实现权限控制,插件可能利用了Servlet Filter或者Spring MVC的Interceptor机制,对请求进行预处理,判断用户是否有权限执行当前操作。 5. **动态权限分配**:在某些情况下,权限可能...
Java Authentication and Authorization Service (JAAS) 是Java平台中用于安全认证和授权的核心组件。它为开发者提供了一种标准的方式来实现用户身份验证和访问控制,从而确保应用程序的安全性。"Jaas in Action"这...