本例是认证的实现,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”验证模块,使用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 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; } }