Java认证和授权服务是Java 2中的一个可选包。
JAAS被用来实现两个目的:
1. 用户认证,为了可靠和安全的确认当前谁在运行Java代码,不管代码是以一个程序运行,还是一个applet,一个bean或者一个servlet。
2. 用户的授权,确保他们对需要执行的动作有访问控制的权利(权限)。
这个部分提供了一个认证组件的初级教程。授权组件将会在JAAS Authorization教程描述。
JAAS认证以插件的形式运行。这允许Java程序与底层的认证技术保持独立。新的或者更新的技术可以在不修改应用程序的前提下嵌入底层模块。一个特定的认证技术的实现可在运行时确定。这个实现在一个登录配置文件中被指定。本指南所用的认证技术是Kerberos。 (See KerberosRequirements.)
教程下面的部分包括下面的内容:
1. 认证教程代码
2. 登录配置
3. 运行代码
4. 用安全管理器运行代码
如果你想先看一下运行代码,可以以直接看第3部分,然后再回来学习编码和配置文件的细节。
我们的认证教程代码包含在一个单独的Java源文件中, JaasAcn.java. 这个文件的主要的方法演示了一个认证过程然后报告认证的结果。
认证用户的代码非常简单,包含下面两步:
1. 初始化LoginContext
2. 调用LoginContext的login方法
首先是基本代码显示,紧随着的是一个完整的清单JaasAcn.java源文件,完成导入语句和错误处理。
为了认证一个用户,首先你需要一个javax.security.auth.login.LoginContext。这初始化一个LoginContext的基本方法:
import javax.security.auth.login.*; . . . LoginContext lc = new LoginContext(<config file entry name>, <CallbackHandler to be used foruser interaction>);
这是我们的教程使用的特殊的初始化方式:
import javax.security.auth.login.*; import com.sun.security.auth.callback.TextCallbackHandler; . . . LoginContext lc = new LoginContext("JaasSample", new TextCallbackHandler());
下面是参数的意义:
1. JAAS登录配置文件中一个条目的名字
这是LoginContext用来在JAAS登录配置文件中为应用查找一个条目。这个条目指定底层的认证技术的实现。这个类必须实现LoginModule接口,这个接口在javax.security.auth.spi
包里。
在我们的简单的代码中,我们用com.sun.security.auth.module包里的Krb5LoginModule
类,这个类实现了Kerberos认证技术。
我们在本教程中使用的配置文件中的这个条目是“JaasSample”,查看jaas.conf文件,所以那是我们传给LoginContext构造方法的第一个参数。
Jaas.conf文件:
/** Login Configuration for the JaasAcn and ** JaasAzn Applications **/ JaasSample { com.sun.security.auth.module.Krb5LoginModule required; };
2. 一个CallbackHandler 实例
当一个需要LoginModule 联系用户的使用,例如询问一个用户的名字和密码,它不会直接联系用户。这是因为有很多种方式可以联系一个用户,保持LoginModules 的与其他类型的用户交互动作的独立是很值得的。而且,LoginModule调用CallbackHandler 来进行用户交互和获取请求的信息,像用户名和密码(CallbackHandler是javax.security.auth.callback包里的一个接口)。
一个特定的CallbackHandler的实例被用来作为第二个参数传给LoginContext的构造方法。LoginContext将此实例转发到下面的LoginModule(在我们的例子中就是Krb5LoginModule)。一个应用通常提供它自己的CallbackHandler 实现。两个简单的CallbackHandlers, com.sun.security.auth.callback
包里的TextCallbackHandlerand DialogCallbackHandler,是一个简单的实现。我们的代码用了TextCallbackHandler,它输出信息到命名行并从命令行读取输入。
一旦我们有了一个LoginContext的实例lc,我们可以调用它的login方法来运行认证过程:
lc.login();
LoginContext初始化一个新的空的javax.security.auth.Subject
对象(这个对象代表被将要被认证的用户或者服务)。LoginContext构造配置的LoginModule(在我们的例子中就是Krb5LoginModule),然后用新的Subject和TextCallbackHandler初始化它。
LoginContext的login方法然后调用Krb5LoginModule 的方法执行登录和认证。Krb5LoginModule 将利用TextCallbackHandler 来获取用户名和密码。然后Krb5LoginModule 将使用这些信息从Kerberos KDC获取用户的证书。See the Kerberos referencedocumentation.
如果认证成功,Krb5LoginModule 用一个KerberosPrincipal 填充这个Subject ,这个Kerberos Principal 代表了这个用户和用户的证书(TGT)。See Subjects,Principals, Authentication, and Credentials forinformation on these terms.
接着,上层的应用程序通过调用LoginContext的getSubject方法检索认证的Subject,尽管在此文档中,这么做是没有必要的。
既然你已经看到了认证一个用户基本的代码,我们可以将它们放到一个类中JaasAcn.java。这包含了相关的import语句和错误处理。
import javax.security.auth.*; import javax.security.auth.callback.*; import javax.security.auth.login.*; import com.sun.security.auth.callback.TextCallbackHandler; /** * This JaasAcn application attempts to authenticate a user * and reports whether or not the authentication was successful. */ public class JaasAcn { public static void main(String[] args) { // Obtain a LoginContext, needed for authentication. Tell // it to use the LoginModule implementation specified by // the entry named "JaasSample" in the JAAS login // configuration file and to also use the specified // CallbackHandler. LoginContext lc = null; try { lc = new LoginContext("JaasSample", new TextCallbackHandler()); } 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); } try { // attempt authentication lc.login(); } catch (LoginException le) { System.err.println("Authentication failed: " System.err.println(" " + le.getMessage()); System.exit(-1); } System.out.println("Authentication succeeded!"); } }
JAAS认证以插件的形式运行,所以应用可以保持与其使用的底层的认证技术的独立。系统管理员可以决定每一个应用的认证技术或者LoginModules,在一个登录配置文件中配置它们。配置信息的源(例如,一个文件或者数据库)是javax.security.auth.login.Configuration 的实现。默认的配置实现是从SunMicrosystems配置文件读取配置信息, asdescribed in com.sun.security.auth.login.ConfigFile.html。
查看JAAS LoginConfiguration File 获取关于什么是登录配置文件,它包含什么,如何指定应该使用的配置文件等更多的信息。
如上所述,本次教程我们用到的配置文件,jaas.conf文件,仅仅包含一个条目:
JaasSample { com.sun.security.auth.module.Krb5LoginModule required; };
这个条目被命名为JaasSample,而是我们的教程应用程序JaasAcn引用的条目的名字。这个条目指定,用来做用户认证的LoginModule 是com.sun.security.auth.module包中的Krb5LoginModule ,Krb5LoginModule为了认证被认为是成功的需要succeed。只有在用户提供的用户名和密码成功的登录到Kerberos KDC。
更多关于Krb5LoginModule参数的信息,请看 Krb5LoginModuledocumentation。
为了运行我们的JAAS认证教程代码,所有你需要做的是:
1. 将JassAcn.java应用的源文件和jass.conf登录配置文件放到一个文件夹中
2. 编译JassAcn.java文件
javac JaasAcn.java
3. 执行JassAcn应用
a) 通过-Djava.security.krb5.realm=<your_realm>指定你的Kerberosrealm。例如,你的realm是KRBNT-OPERATIONS.ABC.COM,你将这样使用:Djava.security.krb5.realm=KRBNT-OPERATIONS.ABC.COM
。
b) 通过-Djava.security.krb5.kdc=<your_kdc>指定你的KerberosKDC。例如,你的KDC是“samplekdc.abc.com”,你可以这样用-Djava.security.krb5.kdc=samplekdc.abc.com
.。
c) 通过-Djava.security.auth.login.config=jaas.conf指定登录配置文件使用jass.conf。
所有的命令在下面。确保用你的Kerberos realm和Kerberos KDC替换必要的值。
java -Djava.security.krb5.realm=<your_realm> -Djava.security.krb5.kdc=<your_kdc> -Djava.security.auth.login.config=jaas.conf JaasAcn
将上边的命令放到一行里。这里分成多行是为了易读。
你将被提示输入你的Kerberos用户名和密码,登录配置文件中指定的底层的Kerberos认证机制将使你登录到Kerberos。如果你登录成功,你将会看到下面的信息:
Authentication succeeded!
如果登录不成功(例如,拼错了你的密码),你将看到:
Authentication failed:
追踪失败的原因。例如,如果输入错误了你的用户名,你将可能看到下面的信息(为了提高易读性,简单的修改了格式):
Authentication failed: Kerberos Authentication Failed: javax.security.auth.login.LoginException: KrbException: Client not found in Kerberos database
登录故障排解的建议,看Troubleshooting。
在修改了一些问题之后,重新运行程序尝试。
当在一个安装了安全管理器的环境中运行Java程序时,这个程序不允许访问资和运行其他的安全敏感的操作,除非它被安全策略明确的给定了做这些的权限。在与J2SE v1.2机器之后的版本兼容的Java平台上,权限必须通过policy文件中的条目被授权。
大多数浏览器安装了安全管理器,所以applet通常运行在一个安全管理器的安全策略之下。在其他的情况下的应用,不是这样,因为一个安全管理器不会再程序运行时自动安装。因此,一个应用,像我们的JaasAcn应用程序,默认对资源有全部的权限。
为了运行一个安全管理器,可以简单的在命令行用Djava.security.manager参数调用解释器。
如果用安全管理器调用JaasAcn,但是不指定任何的策略文件,你讲得到下面的信息(除非你有默认的策略安装在其他地方,指定了必要的权限或者给了全部的权限):
% java -Djava.security.manager \ -Djava.security.krb5.realm=<your_realm> \ -Djava.security.krb5.kdc=<your_kdc> \ -Djava.security.auth.login.config=jaas.conf JaasAcn Exception in thread "main" java.security.AccessControlException: access denied ( javax.security.auth.AuthPermission createLoginContext.JaasSample)
正如你看到的,你将得到一个AccessControlException,因为我们还没有创建和使用策略文件,授权我们代码的权限,为了被允许创建一个LoginContext,这个授权是必要的。
下面是在一个安装了安全管理器的环境中运行我们的应用jaasAcn的完整的步骤。你可以跳过前两部,如果你已经做了根据运行代码部分的步骤做了。
1. 将JassAcn.java和Jaas.conf登录配置文件放到一个文件夹。
2. 编译JaasAcn.java
Javac JassAcn.java
3. 创建一个包含jaasAcn.class的jar文件
Jar –cvf JaasAcn.jar jaasAcn.class
这个命令创建一个jar文件,JaasAcn.java,将JaasAcn.class文件放到里边。
4. 创建一个策略文件,授权给Jar文件需要的权限。
代码尝试创建一个LoginContext需要的权限是一个指定 "createLoginContext.<entryname>"的javax.security.auth.AuthPermission对象。这里, <entryname> 引用登录配置文件中的名字,这个名字也被应用在初始化LoginContext的时候引用。JaasAcn应用的LoginContext初始化使用的名字是”JaasSample“,就像你在下面看到的:
LoginContext lc = new LoginContext("JaasSample", new TextCallbackHandler());
因此,需要授权给JassAcn.jar的权限是:
permission javax.security.auth.AuthPermission "createLoginContext.JaasSample";
拷贝策略文件jaasacn.policy到JassAcn.java所在的目录。这是一个包含了下面的授权信息的文本文件:
grant codebase "file:./JaasAcn.jar" { permission javax.security.auth.AuthPermission "createLoginContext.JaasSample"; };
注意:策略文件和条目的格式在 DefaultPolicy Implementation and Policy File Syntax。权限在这被描述Permissionsin the Java™ SE 6 Development Kit (JDK)。
5. 执行JaasAcn应用程序,指定
a) by an appropriate -classpath
clausethat classes should be searched for in theJaasAcn.jar
JAR file,
b) by -Djava.security.manager
that asecurity manager should be installed,
c) by -Djava.security.krb5.realm=<your_realm>
that yourKerberos realm is the one specified. For example, if your realm is"KRBNT-OPERATIONS.ABC.COM" you'd put -Djava.security.krb5.realm=KRBNT-OPERATIONS.ABC.COM
.
d) by -Djava.security.krb5.kdc=<your_kdc>
that your KerberosKDC is the one specified. For example, if your KDC is"samplekdc.abc.com" you'd put -Djava.security.krb5.kdc=samplekdc.abc.com
.
e) by -Djava.security.policy=jaasacn.policy
that thepolicy file to be used isjaasacn.policy
,and
f) by -Djava.security.auth.login.config=jaas.conf
that thelogin configuration file to be used is jaas.conf
.
下边是整个命令。确保用你的Realm和KDC替换掉。
java -classpath JaasAcn.jar -Djava.security.manager -Djava.security.krb5.realm=<your_realm> -Djava.security.krb5.kdc=<your_kdc> -Djava.security.policy=jaasacn.policy -Djava.security.auth.login.config=jaas.conf JaasAcn
上边的命令键入到一行,这里分开是为了可读性。如果命令对于你的系统来说太长,你将需要将其放到脚本文件里,然后运行脚本文件。
因为指定的策略文件包含一条授权给代码所需权限的条目。JaasAcn将被允许初始化一个LoginContext,然后继续执行。你将被提示输入你的Kerberos用户名和密码,登录配置文件中指定的底层的Kerberos认证机制将使你登录到Kerberos。如果你的登录成功,你将看到Authenticationsucceeded!的信息。如果没有成功,你将看到Authenticationfailed:后边跟着失败的原因。