java jaas_基于Java JAAS表单的身份验证
java jaas
JAASUserPrincipal.java
package com.rainyday.server.login;import java.io.Serializable;import java.security.Principal;/*** @author semika**/public class JAASUserPrincipal implements Principal, Serializable {private String name;/*** @param name*/public JAASUserPrincipal(String name) {if (name == null) {throw new NullPointerException("NULL user name");}this.name = name;}@Overridepublic String getName() {return name;}@Overridepublic String toString() {return "UserPrincipal [name=" + name + "]";}@Overridepublic int hashCode() {final int prime = 31;int result = 1;result = prime * result + ((name == null) ? 0 : name.hashCode());return result;}@Overridepublic boolean equals(Object obj) {if (this == obj)return true;if (obj == null)return false;if (getClass() != obj.getClass())return false;JAASUserPrincipal other = (JAASUserPrincipal) obj;if (name == null) {if (other.name != null)return false;} else if (!name.equals(other.name))return false;return true;}
}
JAASRolePrincipal.java
package com.rainyday.server.login;import java.io.Serializable;import java.security.Principal;/*** @author semika**/public class JAASRolePrincipal implements Principal, Serializable {private String name;/*** @param name*/public JAASRolePrincipal(String name) {if (name == null) {throw new NullPointerException("NULL role name");}this.name = name;}@Overridepublic String getName() {return name;}@Overridepublic String toString() {return "JASSRolePrincipal [name=" + name + "]";}@Overridepublic int hashCode() {final int prime = 31;int result = 1;result = prime * result + ((name == null) ? 0 : name.hashCode());return result;}@Overridepublic boolean equals(Object obj) {if (this == obj)return true;if (obj == null)return false;if (getClass() != obj.getClass())return false;JAASRolePrincipal other = (JAASRolePrincipal) obj;if (name == null) {if (other.name != null)return false;} else if (!name.equals(other.name))return false;return true;}
}
JAASPasswordPrincipal.java
package com.rainyday.server.login;import java.io.Serializable;import java.security.Principal;/*** @author semika**/public class JAASPasswordPrincipal implements Principal, Serializable {private String name;/*** @param name*/public JAASPasswordPrincipal(String name) {if (name == null) {throw new NullPointerException("NULL password.");}this.name = name;}@Overridepublic String getName() {return name;}@Overridepublic int hashCode() {final int prime = 31;int result = 1;result = prime * result + ((name == null) ? 0 : name.hashCode());return result;}@Overridepublic boolean equals(Object obj) {if (this == obj)return true;if (obj == null)return false;if (getClass() != obj.getClass())return false;JAASPasswordPrincipal other = (JAASPasswordPrincipal) obj;if (name == null) {if (other.name != null)return false;} else if (!name.equals(other.name))return false;return true;}@Overridepublic String toString() {return "JAASPasswordPrincipal [name=" + name + "]";}}
rainyDay {com.rainyday.server.login.JAASLoginModule requireddbDriver="com.mysql.jdbc.Driver"dbURL="jdbc:mysql://localhost/rainyday"dbUser="root"dbPassword="abc123"userQuery="select username from secu_user where secu_user.username=? and secu_user.password=?"roleQuery="select secu_user_role.rolename from secu_user, secu_user_role "+ "where secu_user.username=secu_user_role.username and secu_user.username=?"debug=true;
};
“ jass.config”文件应具有类似的格式。 除了登录模块声明之外,您还可以根据需要声明选项。 登录模块可以使用initialize()方法参数中的“ options”映射来使用这些选项。
另外,我们应该通过添加JAVA_OPTS环境变量的路径来告诉tomcat,“ jaas.config”文件的位置。 我将其添加到$ CATALINA_HOME / bin下的'catalina.sh'文件中,如下所示。
JAVA_OPTS =” $ JAVA_OPTS -Djava.security.auth.login.config == .. / conf / jaas.config”
接下来,您需要声明JAASRealm配置。 您可以在$ CATALINA_HOME / conf下的server.xml文件中添加一个新的“ Realm”条目。 在我们的教程中,“领域”条目如下。
<Realm className="org.apache.catalina.realm.JAASRealm"appName="rainyDay"userClassNames="com.rainyday.server.login.JASSUserPrincipal,com.rainyday.server.login.JAASPasswordPrincipal"roleClassNames="com.rainyday.server.login.JASSRolePrincipal"/>
有关apache tomcat的领域配置,您可以查看此文档 。 jaas登录模块的完整源代码。
JAASLoginModule.java
package com.rainyday.server.login;import java.io.IOException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
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;import org.apache.log4j.Logger;/*** @author semika**/
public class JAASLoginModule implements LoginModule { private static Logger LOGGER = Logger.getLogger(JAASLoginModule.class); // initial stateprivate Subject subject;private CallbackHandler callbackHandler;private Map sharedState;private Map options;// configurable optionprivate boolean debug = false;// the authentication statusprivate boolean succeeded = false;private boolean commitSucceeded = false;//user credentialsprivate String username = null;private char[] password = null;//user principleprivate JAASUserPrincipal userPrincipal = null;private JAASPasswordPrincipal passwordPrincipal = null;public JAASLoginModule() {super();}@Overridepublic void initialize(Subject subject, CallbackHandler callbackHandler,Map<string, ?=""> sharedState, Map<string, ?=""> options) {this.subject = subject;this.callbackHandler = callbackHandler;this.sharedState = sharedState;this.options = options;debug = "true".equalsIgnoreCase((String)options.get("debug")); }@Overridepublic boolean login() throws LoginException {if (callbackHandler == null){throw new LoginException("Error: no CallbackHandler available " +"to garner authentication information from the user");}Callback[] callbacks = new Callback[2];callbacks[0] = new NameCallback("username");callbacks[1] = new PasswordCallback("password: ", false);try {callbackHandler.handle(callbacks);username = ((NameCallback)callbacks[0]).getName();password = ((PasswordCallback)callbacks[1]).getPassword();if (debug) {LOGGER.debug("Username :" + username);LOGGER.debug("Password : " + password);}if (username == null || password == null) {LOGGER.error("Callback handler does not return login data properly");throw new LoginException("Callback handler does not return login data properly"); }if (isValidUser()) { //validate user.succeeded = true;return true;} } catch (IOException e) { e.printStackTrace();} catch (UnsupportedCallbackException e) {e.printStackTrace();}return false;}@Overridepublic boolean commit() throws LoginException {if (succeeded == false) {return false;} else { userPrincipal = new JAASUserPrincipal(username);if (!subject.getPrincipals().contains(userPrincipal)) {subject.getPrincipals().add(userPrincipal);LOGGER.debug("User principal added:" + userPrincipal);}passwordPrincipal = new JAASPasswordPrincipal(new String(password)); if (!subject.getPrincipals().contains(passwordPrincipal)) {subject.getPrincipals().add(passwordPrincipal);LOGGER.debug("Password principal added: " + passwordPrincipal);}//populate subject with roles.List<string> roles = getRoles();for (String role: roles) {JAASRolePrincipal rolePrincipal = new JAASRolePrincipal(role);if (!subject.getPrincipals().contains(rolePrincipal)) {subject.getPrincipals().add(rolePrincipal); LOGGER.debug("Role principal added: " + rolePrincipal);}}commitSucceeded = true;LOGGER.info("Login subject were successfully populated with principals and roles"); return true;}}@Overridepublic boolean abort() throws LoginException {if (succeeded == false) {return false;} else if (succeeded == true && commitSucceeded == false) {succeeded = false;username = null;if (password != null) {password = null;}userPrincipal = null; } else {logout();}return true;}@Overridepublic 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[i] = ' ';password = null;}}userPrincipal = null;return true;}private boolean isValidUser() throws LoginException {String sql = (String)options.get("userQuery");Connection con = null;ResultSet rs = null;PreparedStatement stmt = null;try {con = getConnection();stmt = con.prepareStatement(sql);stmt.setString(1, username);stmt.setString(2, new String(password));rs = stmt.executeQuery();if (rs.next()) { //User exist with the given user name and password.return true;}} catch (Exception e) {LOGGER.error("Error when loading user from the database " + e);e.printStackTrace();} finally {try {rs.close();} catch (SQLException e) {LOGGER.error("Error when closing result set." + e);}try {stmt.close();} catch (SQLException e) {LOGGER.error("Error when closing statement." + e);}try {con.close();} catch (SQLException e) {LOGGER.error("Error when closing connection." + e);}}return false;}/*** Returns list of roles assigned to authenticated user.* @return*/private List<string> getRoles() { Connection con = null;ResultSet rs = null;PreparedStatement stmt = null;List<string> roleList = new ArrayList<string>(); try {con = getConnection();String sql = (String)options.get("roleQuery");stmt = con.prepareStatement(sql);stmt.setString(1, username);rs = stmt.executeQuery();if (rs.next()) { roleList.add(rs.getString("rolename")); }} catch (Exception e) {LOGGER.error("Error when loading user from the database " + e);e.printStackTrace();} finally {try {rs.close();} catch (SQLException e) {LOGGER.error("Error when closing result set." + e);}try {stmt.close();} catch (SQLException e) {LOGGER.error("Error when closing statement." + e);}try {con.close();} catch (SQLException e) {LOGGER.error("Error when closing connection." + e);}}return roleList;}/*** Returns JDBC connection* @return* @throws LoginException*/private Connection getConnection() throws LoginException {String dBUser = (String)options.get("dbUser");String dBPassword = (String)options.get("dbPassword");String dBUrl = (String)options.get("dbURL");String dBDriver = (String)options.get("dbDriver");Connection con = null;try {//loading driverClass.forName (dBDriver).newInstance();con = DriverManager.getConnection (dBUrl, dBUser, dBPassword);} catch (Exception e) {LOGGER.error("Error when creating database connection" + e);e.printStackTrace();} finally {}return con;}
}
<login-config><auth-method>FORM</auth-method><realm-name>rainyDay</realm-name><form-login-config><form-login-page>/login.jsp</form-login-page><form-error-page>/error.jsp</form-error-page></form-login-config>
</login-config>
<security-role><role-name>*</role-name>
</security-role>
<security-constraint><web-resource-collection><web-resource-name>Rainy day</web-resource-name><url-pattern>/</url-pattern><http-method>POST</http-method><http-method>GET</http-method></web-resource-collection><auth-constraint><role-name>*</role-name></auth-constraint>
</security-constraint>
由于上述安全限制,如果在没有身份验证的情况下对应用程序受保护区域中的特定资源提出了一些请求,则该请求将被重定向到“登录”页面。 接下来,我将向您展示简单HTML表单,该表单将在表单提交后调用我们的登录模块。
<form id="loginForm" name="loginForm" method="post" action="j_security_check">User Name : <input id="username" type="text" name="j_username" class="textbox"></input>Password : <input id="password" type="password" name="j_password" class="textbox"></input><input name="login" type="submit" value="LOGIN" id="submit" class="button blue"></form>
JAASCallbackHandler.java
package com.rainyday.server.login;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;import org.apache.log4j.Logger;/*** @author semika**/public class JAASCallbackHandler implements CallbackHandler {private static final Logger LOGGER = Logger.getLogger(JAASCallbackHandler.class);private String username = null;private String password = null;/*** @param username* @param password*/public JAASCallbackHandler(String username, String password) {this.username = username;this.password = password;}@Overridepublic void handle(Callback[] callbacks) throws IOException,UnsupportedCallbackException {LOGGER.info("Callback Handler invoked ");for (int i = 0; i < callbacks.length; i++) {if (callbacks[i] instanceof NameCallback) {NameCallback nameCallback = (NameCallback) callbacks[i];nameCallback.setName(username);} else if (callbacks[i] instanceof PasswordCallback) {PasswordCallback passwordCallback = (PasswordCallback) callbacks[i];passwordCallback.setPassword(password.toCharArray());} else {throw new UnsupportedCallbackException(callbacks[i], "The submitted Callback is unsupported");}}}
}
接下来,我们必须创建一个' LoginContext'实例来显式调用身份验证。
LoginContext lc = null;try {lc = new LoginContext("rainyDay", new JAASCallbackHandler(username, password));lc.login();//get the subject.Subject subject = lc.getSubject();//get principalssubject.getPrincipals();LOGGER.info("established new logincontext");} catch (LoginException e) {LOGGER.error("Authentication failed " + e);}
参考:来自我们的JCG合作伙伴 Semika loku kaluge的基于Java表单的身份验证 ,位于Code Box博客上。
翻译自: https://www.javacodegeeks.com/2012/06/java-jaas-form-based-authentication.html
java jaas
java jaas_基于Java JAAS表单的身份验证相关推荐
- glassfish hk2_使用GlassFish 3.1.2.2和Primefaces 3.4的JDBC领域和基于表单的身份验证
glassfish hk2 我的博客上最受欢迎的帖子之一是有关JDBC安全领域和带有Primefaces的GlassFish上基于表单的身份验证的简短教程. 在收到有关它不再适用于最新的GlassFi ...
- 使用GlassFish 3.1.2.2和Primefaces 3.4的JDBC领域和基于表单的身份验证
我的博客上最受欢迎的帖子之一是有关JDBC安全领域和带有Primefaces的GlassFish上基于表单的身份验证的简短教程. 在收到有关它不再适用于最新的GlassFish 3.1.2.2的评论后 ...
- ASP.NET 完成基于表单的身份验证
实现:验证用户身份成功,并登陆后台Admin文件夹里的index.aspx后台管理首页面,否则禁止匿名用户访问项目中的Admin文件夹里的任何一个文件. 步骤一: 在根目录下的web.config ...
- 傻瓜教程:asp.net(c#) 如何配置authentication,完成基于表单的身份验证
傻瓜老师又来了,本讲座报以学以致用,师傅带进门 修行靠个人的精神,不深入探讨,还请多指教~ 这堂课将的是基于表单的身份验证,其实某些时候,用于验证身份的账户和密码并不需要存在数据库或配置文件里,这时 ...
- 【FBA】SharePoint 2013自定义Providers在基于表单的身份验证(Forms-Based-Authentication)中的应用...
//http://www.cnblogs.com/OceanEyes/p/custom-provider-in-sharepoint-2013-fba-authentication.html 由于项目 ...
- primefaces_使用WildFly 8.2.0.Final,Primefaces 5.1和MySQL 5的JDBC领域和基于表单的身份验证...
primefaces 我会不时查看我博客上最受欢迎的内容,并尝试最好地满足您的需求. 因此,阅读我的博客是其他读者推动内容的一种方式. 另一种方法是通过评论或电子邮件与我联系. 今天,我将使用Prim ...
- 使用WildFly 8.2.0.Final,Primefaces 5.1和MySQL 5的JDBC领域和基于表单的身份验证
我会不时查看我博客上最受欢迎的内容,并尽力满足您的最佳需求. 因此,阅读我的博客是其他读者推动内容的一种方式. 另一种方法是通过评论或电子邮件与我联系. 今天,我将使用Primefaces修改我的JD ...
- ASP.NET MVC 4 (十三) 基于表单的身份验证
在前面的章节中我们知道可以在MVC应用程序中使用[Authorize]特性来限制用户对某些网址(控制器/控制器方法)的访问,但这都是在对用户认证之后,而用户的认证则依然是使用ASP.NET平台的认证机 ...
- Java EE MVC:处理表单验证
在本文中,我们将介绍Java EE MVC中的表单验证. Java EE MVC与Java Bean验证API( JSR 303 )集成在一起,这使得添加验证约束变得非常容易. 使用JAX-RS方式进 ...
最新文章
- C#获取邮件客户端保存的邮箱密码
- Boosting for PRML
- HTTP、TCP、UDP,Socket,HTTPS
- DEBUG_NEW和THIS_FILE
- JQuery文件上传控件Uploadify文档
- kotlin mysql数据库_在kotlin中使用mysql行级锁
- Java IO学习第二天部分详解
- 中兴V880使用手记之二——取得root权限
- 三维点云学习(2)五种算法比较
- python︱Anaconda安装、简介(安装报错问题解决、Jupyter Notebook)
- Djangon 基础总结 汇总 从请求到返回页面的过程,
- matlab遗传工具箱ga,用遗传算法工具箱(GA)识别Bouc-Wen模型微分方程参数
- 辉哥基于android S 分析过度动画以及窗口动画
- composer 报错:composer [ReflectionException] Class Fxp\Composer\AssetPlugin\Repository\NpmRepository
- [专利与论文-12]:高级职称评定的面试和答辩注意事项
- 硬盘那些事(Windows系统下磁盘格式的优缺点)
- 国产运动耳机哪个牌子的好、六款运动耳机品牌推荐
- 【条码检测算法】不起眼的条码识别也能玩出这么多花样
- STM32单片机开发实例 基于STM32单片机的智能行李箱
- [AV1] 谈谈AV1中的 S-Frame
热门文章
- laravel构造器的CURD
- C++描述杭电OJ 2000. ASCII码排序 ||
- avue中实现消息的实时展示
- 3分钟内看完这,bootstraptable表格控件,受益匪浅!
- tomcat 实现 文件共享,查看文件目录
- php 输出01,php基础01_thinkphp输出Hello World-Go语言中文社区
- 2019最新 Java商城秒杀系统的设计与实战视频教程(SpringBoot版)
- android 新的布局,Android新布局方式ConstraintLayout快速入门教程
- es dsl多条件组合查询(转)
- Multi-catch parameters are not allowed for source level below 1.7 解决方法