Java认证和授权服务 JAAS 之 认证
来源:互联网 发布:淘宝交易款临时冻结 编辑:程序博客网 时间:2024/05/22 08:17
LoginModule
它是认证服务器端的实现,用于验证客户端的信息,实现者实现 javax.security.auth.spi.LoginModule 接口的 login、commit、abort、logout 方法来完成用户的登录和登出操作,示例代码:
package jaas;import javax.security.auth.Subject;import javax.security.auth.callback.*;import javax.security.auth.login.FailedLoginException;import javax.security.auth.login.LoginException;import javax.security.auth.spi.LoginModule;import java.security.Principal;import java.util.Map;public class MyLoginModule implements LoginModule { // username and password private String username; private char[] password; // the authentication status private boolean userPwdSucceeded = false; private boolean commitSucceeded = false; // user's Principal private Principal userPrincipal; // initial state private Subject subject; private CallbackHandler callbackHandler; /** * Initialize this <code>LoginModule</code>. */ public void initialize(Subject subject, CallbackHandler callbackHandler, Map<java.lang.String, ?> sharedState, Map<java.lang.String, ?> options) { this.subject = subject; this.callbackHandler = callbackHandler; } /** * Authenticate the user by prompting for a user name and password. */ public boolean login() throws LoginException { // prompt for a user name and password if (callbackHandler == null) throw new LoginException("Error: no CallbackHandler available " + "to garner authentication information from the user"); Callback[] callbacks = new Callback[4]; callbacks[0] = new NameCallback("user name"); callbacks[1] = new PasswordCallback("password", false); callbacks[2] = new TextOutputCallback(TextOutputCallback.INFORMATION, "hello, just a msg!"); callbacks[3] = new TextOutputCallback(TextOutputCallback.WARNING, "just warn you!"); try { callbackHandler.handle(callbacks); NameCallback nameCallback = (NameCallback) callbacks[0]; PasswordCallback passwordCallback = (PasswordCallback) callbacks[1]; username = nameCallback.getName(); char[] tmpPassword = passwordCallback.getPassword(); passwordCallback.clearPassword();// clean password in memory space if (tmpPassword == null) { tmpPassword = new char[0];// treat a NULL password as an empty password } password = new char[tmpPassword.length]; System.arraycopy(tmpPassword, 0, password, 0, tmpPassword.length); } catch (Exception e) { e.printStackTrace(); } // verify the username/password boolean usernameCorrect = false; if (username.equals("user")) usernameCorrect = true; if (usernameCorrect && password.length == 3 && password[0] == 'p' && password[1] == 'w' && password[2] == 'd') { userPwdSucceeded = true; } else { userPwdSucceeded = false; cleanUserAndPwdData(); if (!usernameCorrect) { throw new FailedLoginException("User Name Incorrect"); } else { throw new FailedLoginException("Password Incorrect"); } } return userPwdSucceeded; } public boolean commit() throws LoginException { if (!userPwdSucceeded) return false; // add a Principal (authenticated identity) to the Subject userPrincipal = new SamplePrincipal(username); subject.getPrincipals().add(userPrincipal); // in any case, clean out state cleanUserAndPwdData(); return commitSucceeded = true; } public boolean abort() throws LoginException { if (!userPwdSucceeded) return false; if (commitSucceeded) { logout(); } else { cleanState(); } return true; } public boolean logout() throws LoginException { subject.getPrincipals().remove(userPrincipal); cleanState(); userPwdSucceeded = commitSucceeded; return true; } private void cleanState() { userPwdSucceeded = false; cleanUserAndPwdData(); userPrincipal = null; } private void cleanUserAndPwdData() { username = null; if (password != null) { for (int i = 0; i < password.length; i++) password[i] = ' '; password = null; } }}
test_jaas.config 登录配置文件
/** 登录配置 **/Sample { jaas.MyLoginModule required debug=true;};
Principal 用户身份信息
示例代码:
package jaas;import java.security.Principal;public class SamplePrincipal implements Principal { private String name; public SamplePrincipal(String name) { this.name = name; } public String getName() { return 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(); }}
CallbackHandler 用户交互回调接口
用户代码通过该回调可传入用户名、密码 或其它信息 供 验证服务器使用,java 预置了多种回调实现:
* @see javax.security.auth.callback.ChoiceCallback * @see javax.security.auth.callback.ConfirmationCallback * @see javax.security.auth.callback.LanguageCallback * @see javax.security.auth.callback.NameCallback * @see javax.security.auth.callback.PasswordCallback * @see javax.security.auth.callback.TextInputCallback * @see javax.security.auth.callback.TextOutputCallback示例代码:
package jaas;import javax.security.auth.callback.*;import java.io.IOException;public class MyCallbackHandler implements CallbackHandler { public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException { for (int i = 0; i < callbacks.length; i++) { if (callbacks[i] instanceof TextOutputCallback) {// display the message according to the specified type TextOutputCallback toc = (TextOutputCallback) callbacks[i]; switch (toc.getMessageType()) { case TextOutputCallback.INFORMATION: System.out.println(toc.getMessage()); break; case TextOutputCallback.ERROR: System.err.println("ERROR: " + toc.getMessage()); break; case TextOutputCallback.WARNING: System.err.println("WARNING: " + toc.getMessage()); break; default: throw new IOException("Unsupported message type: " + toc.getMessageType()); } } else if (callbacks[i] instanceof NameCallback) {// prompt the user for a username NameCallback nc = (NameCallback) callbacks[i]; String name = "user";// TODO 这里可以实现为从控制台允许用户输入等方式接收用户参数。。。 nc.setName(name); } else if (callbacks[i] instanceof PasswordCallback) {// prompt the user for sensitive information PasswordCallback pc = (PasswordCallback) callbacks[i]; String pwd = "pwd";// TODO 这里可以实现为从控制台允许用户输入等方式接收用户参数。。。 pc.setPassword(pwd.toCharArray()); } else { throw new UnsupportedCallbackException (callbacks[i], "Unrecognized Callback"); } } }}
测试
当登录模块和用户回调实现好以后,就可以进行测试,示例代码:
package jaas;import javax.security.auth.Subject;import javax.security.auth.login.LoginContext;import javax.security.auth.login.LoginException;public class Main { public static void main(String[] args) throws LoginException { // 配置文件中查找 Sample 名字的 LoginModule,并指定 CallbackHandler LoginContext lc = new LoginContext("Sample", new MyCallbackHandler()); try { lc.login(); Subject subject = lc.getSubject();// System.out.println(subject); System.out.println("Authentication succeeded!"); } catch (LoginException le) { System.err.println("Authentication failed:" + le.getMessage()); } }}
注意,上述的 new LoginContext("Sample", new MyCallbackHandler()); 是将 登录模块和用户回调关联起来,Sample为登录配置文件中指定的名字,java的jaas服务会通过 -D参数读取并初始化该登录模块,回调接口为用户自定义的交互对象,运行参数如下:
-Djava.security.auth.login.config=/xx/test/test_jaas.config
运行结果
由于示例代码中在 MyCallbackHandler 中硬编码指定了正确的用户名和密码,所以可以看到正确的输出:“Authentication succeeded!”
MyCallbackHandler 为自定义的交互类,可以实现为通过 web 请求中获取用户名和密码,或者从控制台 System.in 接收输入的用户名和密码等。
阅读全文
0 0
- Java认证和授权服务 JAAS 之 认证
- Java认证和授权服务 JAAS 之 授权
- JAAS:java授权与认证服务
- java安全 ——JAAS(Java 认证和授权服务)开发指南
- java安全 ——JAAS(Java 认证和授权服务)开发指南
- jaas的认证和授权基本理解
- 结合JAAS实现J2EE的安全认证和授权
- Jboss+EJB3下使用JAVA验证和授权服务(JAAS)
- Java安全之认证与授权
- Java安全之认证与授权
- Java安全之认证与授权
- JAAS之快速开发JBOSS自定义认证
- mongodb之认证授权
- Java Web系列:认证和授权基础
- 认证授权和审计
- 安全性测试之认证授权
- 安全测试之认证授权
- java shiro认证以及授权
- 1009-1012
- Ubuntu 下安装Go语言
- 前端工程师进阶
- [Java--定时器]--定时器举例
- 多线程之读写锁ReentrantReadWriteLock
- Java认证和授权服务 JAAS 之 认证
- visual studio 卸载 vsassistx工具
- js设置title属性的值的换行问题
- 浏览器兼容之JavaScript篇——已在IE、FF、Chrome测试
- JS控制HTML元素的显示和隐藏+网站浮标
- Spring 加载多个配置文件
- Java读取Excel异常NoSuchMethodError
- Lua学习笔记5-循环
- 1 java基本语法(未完待续)