有哪位朋友在实际项目中使用过jaas的吗?(100分)

  • 主题发起人 主题发起人 leozmy
  • 开始时间 开始时间
L

leozmy

Unregistered / Unconfirmed
GUEST, unregistred user!
请谈谈经验,注意事项,不足之处,都可以,随便说。
我想在项目中使用jaas来做认证,它看起来挺不错的。
 
以下文章摘自<计算机世界>
JavaTM Authen
tication and Authorization Service (JAAS)在JavaTM 2 SDK Standard Edition (J2SDK)1.3版本中是一个可选的包,而现在JAAS已经整合到J2SDK1.4中.
有两种情况使用JAAS:
1.用来鉴定用户,能够可靠并安全的确定谁在执行java代码,而不管执行的是一个应用程序或小程序或bean或java servlet;
2.授权用户并保证用户能有通路控制执行许可.
JAAS实现一个java版本的standard Pluggable Authen
tication Module (PAM)的框架.传统上java提供一个原代码的通路控制(通路控制基于代码来源和谁签名).它所缺乏的是基于谁在运行代码的强制通路控制能力.JAAS提供了一个框架增加了安全性来支持这种功能.
JAAS是一种可插入的风格.这可以使应用程序对鉴定技术保持独立性.新的或更新的鉴定技术能够插入应用程序下面而不需要修改程序本身.应用程序可以例示一 个LoginContext对象依此提及一个确定鉴定技术的Configuration或用来执行鉴定的LoginModule来允许鉴定.LoginModule可以提示和检验用户名和用户密码.其他的也可以读出和检验一个声音或一个指纹.
当用户或服务器执行的代码被鉴定以后,JAAS组件与java通路控制模式一起保护敏感资源的通路.不像J2SDK13或以上版本通路控制决定由代码位置和代码签名者,J2SDK14通路控制决定有运行代码的代码源和用户或服务器.假如鉴定成功,Subject被LoginModule用相关的Principals和信任书更新.
从下一个例子中可以看出JAAS中Authen
tication的作用.
1.SampleAcn.java

package sample;

import java.io.*;
import java.util.*;
import javax.security.auth.login.*;
import javax.security.auth.*;
import javax.security.auth.callback.*;

//for a simple Authen
tication .
public class SampleAcn {

public static void main(String[] args) {

LoginContext lc = null;
try {
/*为了鉴别用户,首先需要一个javax.security.auth.login.LoginContext.
1.参数"Sample"是JAAS注册配置文件的入口名字.一个入口指定实现了 鉴别技术的类,这个类必须实现LoginModule(在javax.security.auth.spi中)接口;
2.CallbackHandler的实例化.当一个LoginModule需要与用户通信,如请求用户名
或用户密码,它需要保持独立性因为用户通信有许多方式.LoginModule调用javax.security.auth.callback.CallbackHandler
去执行与用户通信和获得请求信息包括用户名用户密码.
*/
lc = new LoginContext("Sample", new MyCallbackHandler());
} 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);
}

int i;
for (i = 0;
i < 3;
i++) {
try {

/**
* 调用LoginContext中login方法.LoginContext例式一个空的javax.security.auth.Subject对象,
* (描述被鉴定的用户或服务器).login方法调用LoginModule中的方法执行注册和鉴定.
* SampleLoginModule利用MyCallbackHandler获得用户名和用户密码.SampleLoginModule将
* 检查用户名和用户密码.
*/
lc.login();

// if we return with no exception, authen
tication succeeded
break;

} catch (LoginException le) {

System.err.println("Authen
tication failed:");
System.err.println(" " + le.getMessage());
try {
Thread.currentThread().sleep(3000);
} catch (Exception e) {
// ignore
}
}
}

// did they fail three times?
if (i == 3) {
System.out.println("Sorry");
System.exit(-1);
}
System.out.println("Authen
tication succeeded!");
}
}

class MyCallbackHandler implements CallbackHandler {

public void handle(Callback[] callbacks)
throws IOException, UnsupportedCallbackException {

for (int i = 0;
i < callbacks.length;
i++) {
if (callbacks instanceof TextOutputCallback) {

// display the message according to the specified type
TextOutputCallback toc = (TextOutputCallback)callbacks;
switch (toc.getMessageType()) {
case TextOutputCallback.INFORMATION:
System.out.println(toc.getMessage());
break;
case TextOutputCallback.ERROR:
System.out.println("ERROR: " + toc.getMessage());
break;
case TextOutputCallback.WARNING:
System.out.println("WARNING: " + toc.getMessage());
break;
default:
throw new IOException("Unsupported message type: " +
toc.getMessageType());
}

} else
if (callbacks instanceof NameCallback) {

// prompt the user for a username
NameCallback nc = (NameCallback)callbacks;

System.err.print(nc.getPrompt());
System.err.flush();
nc.setName((new BufferedReader
(new InputStreamReader(System.in))).readLine());

} else
if (callbacks instanceof PasswordCallback) {

// prompt the user for sensitive information
PasswordCallback pc = (PasswordCallback)callbacks;
System.err.print(pc.getPrompt());
System.err.flush();
pc.setPassword(readPassword(System.in));

} else
{
throw new UnsupportedCallbackException
(callbacks, "Unrecognized Callback");
}
}
}

private char[] readPassword(InputStream in) throws IOException {

char[] lineBuffer;
char[] buf;
int i;

buf = lineBuffer = new char[128];

int room = buf.length;
int offset = 0;
int c;

loop: while (true) {
switch (c = in.read()) {
case -1:
case '/n':
break loop;

case '/r':
int c2 = in.read();
if ((c2 != '/n') &amp;&amp;
(c2 != -1)) {
if (!(in instanceof PushbackInputStream)) {
in = new PushbackInputStream(in);
}
((PushbackInputStream)in).unread(c2);
} else

break loop;

default:
if (--room < 0) {
buf = new char[offset + 128];
room = buf.length - offset - 1;
System.arraycopy(lineBuffer, 0, buf, 0, offset);
Arrays.fill(lineBuffer, ' ');
lineBuffer = buf;
}
buf[offset++] = (char) c;
break;
}
}

if (offset == 0) {
return null;
}

char[] ret = new char[offset];
System.arraycopy(buf, 0, ret, 0, offset);
Arrays.fill(buf, ' ');

return ret;
}
}
2. SampleLoginModule.java
package sample.module;

import java.util.*;
import java.io.IOException;
import javax.security.auth.*;
import javax.security.auth.callback.*;
import javax.security.auth.login.*;
import javax.security.auth.spi.*;
import sample.principal.SamplePrincipal;

public class SampleLoginModule implements LoginModule {

// initial state
private Subject subject;
private CallbackHandler callbackHandler;
private Map sharedState;
private Map options;

// 配置选项.
private boolean debug = false;

//鉴别状况
private boolean succeeded = false;
private boolean commitSucceeded = false;

//用户名和用户密码.
private String username;
private char[] password;

//用户的Principal
private SamplePrincipal userPrincipal;

public void initialize(Subject subject, CallbackHandler callbackHandler,
Map sharedState, Map options) {

this.subject = subject;
this.callbackHandler = callbackHandler;
this.sharedState = sharedState;
this.options = options;

// initialize any configured options
debug = "true".equalsIgnoreCase((String)options.get("debug"));
}

public boolean login() throws LoginException {

//提示用户名和用户密码.
if (callbackHandler == null)
throw new LoginException("Error: no CallbackHandler available " +
"to garner authen
tication information from the user");

Callback[] callbacks = new Callback[2];
callbacks[0] = new NameCallback("user name: ");
callbacks[1] = new PasswordCallback("password: ", false);

try {
callbackHandler.handle(callbacks);
username = ((NameCallback)callbacks[0]).getName();
char[] tmpPassword = ((PasswordCallback)callbacks[1]).getPassword();
if (tmpPassword == null) {
// treat a NULL password as an empty password
tmpPassword = new char[0];
}
password = new char[tmpPassword.length];
System.arraycopy(tmpPassword, 0,
password, 0, tmpPassword.length);
((PasswordCallback)callbacks[1]).clearPassword();

} catch (java.io.IOException ioe) {
throw new LoginException(ioe.toString());
} catch (UnsupportedCallbackException uce) {
throw new LoginException("Error: " + uce.getCallback().toString() +
" not available to garner authen
tication information " +
"from the user");
}

//打印调试信息.
if (debug) {
System.out.println("/t/t[SampleLoginModule] " +
"user entered user name: " +
username);
System.out.print("/t/t[SampleLoginModule] " +
"user entered password: ");
for (int i = 0;
i < password.length;
i++)
System.out.print(password);
System.out.println();
}

//检验用户名和用户密码.默认是"testUser"和"testPassword"
boolean usernameCorrect = false;
boolean passwordCorrect = false;
if (username.equals("testUser"))
usernameCorrect = true;
if (usernameCorrect &amp;&amp;
password.length == 12 &amp;&amp;
password[0] == 't' &amp;&amp;
password[1] == 'e' &amp;&amp;
password[2] == 's' &amp;&amp;
password[3] == 't' &amp;&amp;
password[4] == 'P' &amp;&amp;
password[5] == 'a' &amp;&amp;
password[6] == 's' &amp;&amp;
password[7] == 's' &amp;&amp;
password[8] == 'w' &amp;&amp;
password[9] == 'o' &amp;&amp;
password[10] == 'r' &amp;&amp;
password[11] == 'd') {

//鉴别成功.
passwordCorrect = true;
if (debug)
System.out.println("/t/t[SampleLoginModule] " +
"authen
tication succeeded");
succeeded = true;
return true;
} else
{

//鉴别失败.--------清除输出状态.
if (debug)
System.out.println("/t/t[SampleLoginModule] " +
"authen
tication failed");
succeeded = false;
username = null;
for (int i = 0;
i < password.length;
i++)
password = ' ';
password = null;
if (!usernameCorrect) {
throw new FailedLoginException("User Name Incorrect");
} else
{
throw new FailedLoginException("Password Incorrect");
}
}
}

public boolean commit() throws LoginException {
if (succeeded == false) {
return false;
} else
{
//假设我们鉴别的用户是SamplePrincipal.
userPrincipal = new SamplePrincipal(username);
if (!subject.getPrincipals().contains(userPrincipal))
subject.getPrincipals().add(userPrincipal);

if (debug) {
System.out.println("/t/t[SampleLoginModule] " +
"added SamplePrincipal to Subject");
}

username = null;
for (int i = 0;
i < password.length;
i++)
password = ' ';
password = null;

commitSucceeded = true;
return true;
}
}

public boolean abort() throws LoginException {
if (succeeded == false) {
return false;
} else
if (succeeded == true &amp;&amp;
commitSucceeded == false) {
// login succeeded but overall authen
tication failed
succeeded = false;
username = null;
if (password != null) {
for (int i = 0;
i < password.length;
i++)
password = ' ';
password = null;
}
userPrincipal = null;
} else
{
logout();
}
return true;
}

public boolean logout() throws LoginException {

subject.getPrincipals().remove(userPrincipal);
succeeded = false;
succeeded = commitSucceeded;
username = null;
if (password != null) {
for (int i = 0;
i < password.length;
i++)
password = ' ';
password = null;
}
userPrincipal = null;
return true;
}
}
3. SamplePrincipal.java:
package sample.principal;

import java.security.Principal;

public class SamplePrincipal implements Principal, java.io.Serializable {

private String name;

public SamplePrincipal(String name) {
if (name == null)
throw new NullPointerException("illegal null input");

this.name = name;
}

public String getName() {
return name;
}

public String toString() {
return("SamplePrincipal: " + name);
}

public boolean equals(Object o) {
if (o == null)
return false;

if (this == o)
return true;

if (!(o instanceof SamplePrincipal))
return false;
SamplePrincipal that = (SamplePrincipal)o;

if (this.getName().equals(that.getName()))
return true;
return false;
}

public int hashCode() {
return name.hashCode();
}
}
4. 配置文件:sample_jaas.config:
Sample {
sample.module.SampleLoginModule required debug=true;
};
编译SampleAcn.java ,SampleLoginModule.java,SamplePrincipal.java 到d:/temp(如:javac -d d:/temp SampleAcn.java SampleLoginModule.java,SamplePrincipal.java),然后将sample_jaas_config放入d:/temp目录,然后运行java -Djava.security.auth.login.config==sample_jaas.config sample.SampleAcn
系统要求输入用户名和密码,输入:testUser 和testPassword,如果鉴别成功,将输出:
user name: testUser
password: testPassword
[SampleLoginModule] user entered user name: testUser
[SampleLoginModule] user entered password: testPassword
[SampleLoginModule] authen
tication succeeded
[SampleLoginModule] added SamplePrincipal to Subject
Authen
tication succeeded!
 
:only you
非常感谢回复。
我在ibm网上也看到了一个与此类似的教程。
有没有什么实际的经验之谈?
 
没有,我接触这方面还比较少,我对于JAVA也是个学徒工
 
:only you
总之,谢谢你。
帖子在这边放几天再结束吧。
希望有人用过。
 
哈哈,上次的分数又退回来了!
再发!
 
后退
顶部