本例是认证的实现,JAAS定义了可插拔的认证机制,使认证逻辑独立开来,可通过修改配置文件切换认证模块。
官方参考:
http://java.sun.com/products/archive/jaas/
http://java.sun.com/j2se/1.4.2/docs/guide/security/jaas/JAASRefGuide.html
security.pdf
一、配置文件及设置
1. 配置文件(假设为D:/jaas.conf):
- Sample
- {
- com.fastunit.samples.jaas.SampleLoginModule required debug=false;
- };
Sample
{
com.fastunit.samples.jaas.SampleLoginModule required debug=false;
};
此文件定义了一个“Sample”验证模块,使用SampleLoginModule来进行验证。
2. 启用配置文件:
-Djava.security.auth.login.config=D:/jaas.conf
二、客户端调用
- package javaapplication3;
- import javax.security.auth.login.LoginContext;
- import javax.security.auth.login.LoginException;
- /**
- *
- * @author Dao
- */
- public class LoginManager
- {
- public LoginManager()
- {
- }
- public static void main(String[] args)
- {
- try
- {
- String username = "username";
- String password = "password";
- //此处指定了使用配置文件的“Sample"验证模块,对应的实现类为SampleLoginModule
- LoginContext lc = new LoginContext("Sample", new SampleCallbackHandler(username, password));
- //进行登录操作,如果验证失败会抛出异常
- lc.login();
- }
- catch (LoginException e)
- {
- e.printStackTrace();
- }
- catch (SecurityException e)
- {
- e.printStackTrace();
- }
- }
- }
package javaapplication3;
import javax.security.auth.login.LoginContext;
import javax.security.auth.login.LoginException;
/**
*
* @author Dao
*/
public class LoginManager
{
public LoginManager()
{
}
public static void main(String[] args)
{
try
{
String username = "username";
String password = "password";
//此处指定了使用配置文件的“Sample"验证模块,对应的实现类为SampleLoginModule
LoginContext lc = new LoginContext("Sample", new SampleCallbackHandler(username, password));
//进行登录操作,如果验证失败会抛出异常
lc.login();
}
catch (LoginException e)
{
e.printStackTrace();
}
catch (SecurityException e)
{
e.printStackTrace();
}
}
}
- package javaapplication3;
- 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;
- /**
- *
- * @author Dao
- */
- public class SampleCallbackHandler implements CallbackHandler
- {
- private String username;
- private String password;
- public SampleCallbackHandler(String username, String password)
- {
- this.username = username;
- this.password = password;
- }
- public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException
- {
- for (int i = 0; i < callbacks.length; i++)
- {
- if (callbacks[i] instanceof NameCallback)
- {
- NameCallback ncb = (NameCallback) callbacks[i];
- ncb.setName(this.username);
- }
- else if (callbacks[i] instanceof PasswordCallback)
- {
- PasswordCallback pcb = (PasswordCallback) callbacks[i];
- pcb.setPassword(this.password.toCharArray());
- }
- }
- }
- }
package javaapplication3;
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;
/**
*
* @author Dao
*/
public class SampleCallbackHandler implements CallbackHandler
{
private String username;
private String password;
public SampleCallbackHandler(String username, String password)
{
this.username = username;
this.password = password;
}
public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException
{
for (int i = 0; i < callbacks.length; i++)
{
if (callbacks[i] instanceof NameCallback)
{
NameCallback ncb = (NameCallback) callbacks[i];
ncb.setName(this.username);
}
else if (callbacks[i] instanceof PasswordCallback)
{
PasswordCallback pcb = (PasswordCallback) callbacks[i];
pcb.setPassword(this.password.toCharArray());
}
}
}
}
三、验证实现
- package javaapplication3;
- import java.io.IOException;
- 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.LoginException;
- import javax.security.auth.spi.LoginModule;
- /**
- *
- * @author Dao
- */
- public class SampleLoginModule implements LoginModule
- {
- private boolean isAuthenticated = false;
- private CallbackHandler callbackHandler;
- private Subject subject;
- private SamplePrincipal principal;
- public SampleLoginModule()
- {
- }
- public void initialize(Subject subject, CallbackHandler callbackHandler, Map<String, ?> sharedState, Map<String, ?> options)
- {
- this.subject = subject;
- this.callbackHandler = callbackHandler;
- }
- public boolean login() throws LoginException
- {
- try
- {
- NameCallback nameCallback = new NameCallback("username");
- PasswordCallback passwordCallback = new PasswordCallback("password", false);
- Callback[] calls = new Callback[]{nameCallback, passwordCallback};
- this.callbackHandler.handle(calls);
- //获得用户数据
- String username = nameCallback.getName();
- String password = String.valueOf(passwordCallback.getPassword());
- //TODO验证,如:查询数据库、LDAP。。。
- if (true) //此处省去了实际的验证逻辑,在此假设验证通过
- {
- this.principal = new SamplePrincipal(username);
- this.isAuthenticated = true;
- }
- else
- {
- throw new LoginException("user or password is wrong");
- }
- }
- catch (IOException e)
- {
- throw new LoginException("no such user");
- }
- catch (UnsupportedCallbackException e)
- {
- throw new LoginException("login failure");
- }
- return this.isAuthenticated;
- }
- /**
- * 验证后处理,在Subject中加入用户对象
- * @return
- * @throws javax.security.auth.login.LoginException
- */
- public boolean commit() throws LoginException
- {
- if (this.isAuthenticated)
- {
- this.subject.getPrincipals().add(this.principal);
- }
- else
- {
- throw new LoginException("Authentication failure");
- }
- return this.isAuthenticated;
- }
- public boolean abort() throws LoginException
- {
- return false;
- }
- public boolean logout() throws LoginException
- {
- this.subject.getPrincipals().remove(this.principal);
- this.principal = null;
- return true;
- }
- }
package javaapplication3;
import java.io.IOException;
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.LoginException;
import javax.security.auth.spi.LoginModule;
/**
*
* @author Dao
*/
public class SampleLoginModule implements LoginModule
{
private boolean isAuthenticated = false;
private CallbackHandler callbackHandler;
private Subject subject;
private SamplePrincipal principal;
public SampleLoginModule()
{
}
public void initialize(Subject subject, CallbackHandler callbackHandler, Map<String, ?> sharedState, Map<String, ?> options)
{
this.subject = subject;
this.callbackHandler = callbackHandler;
}
public boolean login() throws LoginException
{
try
{
NameCallback nameCallback = new NameCallback("username");
PasswordCallback passwordCallback = new PasswordCallback("password", false);
Callback[] calls = new Callback[]{nameCallback, passwordCallback};
this.callbackHandler.handle(calls);
//获得用户数据
String username = nameCallback.getName();
String password = String.valueOf(passwordCallback.getPassword());
//TODO验证,如:查询数据库、LDAP。。。
if (true) //此处省去了实际的验证逻辑,在此假设验证通过
{
this.principal = new SamplePrincipal(username);
this.isAuthenticated = true;
}
else
{
throw new LoginException("user or password is wrong");
}
}
catch (IOException e)
{
throw new LoginException("no such user");
}
catch (UnsupportedCallbackException e)
{
throw new LoginException("login failure");
}
return this.isAuthenticated;
}
/**
* 验证后处理,在Subject中加入用户对象
* @return
* @throws javax.security.auth.login.LoginException
*/
public boolean commit() throws LoginException
{
if (this.isAuthenticated)
{
this.subject.getPrincipals().add(this.principal);
}
else
{
throw new LoginException("Authentication failure");
}
return this.isAuthenticated;
}
public boolean abort() throws LoginException
{
return false;
}
public boolean logout() throws LoginException
{
this.subject.getPrincipals().remove(this.principal);
this.principal = null;
return true;
}
}
- package javaapplication3;
- import java.security.Principal;
- /**
- *
- * @author Dao
- */
- public class SamplePrincipal implements Principal
- {
- private String name;
- public SamplePrincipal(String name)
- {
- this.name = name;
- }
- public String getName()
- {
- return name;
- }
- public boolean equals(Object ob)
- {
- if (ob instanceof SamplePrincipal)
- {
- SamplePrincipal principal = (SamplePrincipal) ob;
- return this.name.equalsIgnoreCase(principal.getName());
- }
- return false;
- }
- public int hashCode()
- {
- return name.toUpperCase().hashCode();
- }
- }