本站首页    管理页面    写新日志    退出


«August 2025»
12
3456789
10111213141516
17181920212223
24252627282930
31


公告
 本博客在此声明所有文章均为转摘,只做资料收集使用。

我的分类(专题)

日志更新

最新评论

留言板

链接

Blog信息
blog名称:
日志总数:1304
评论数量:2242
留言数量:5
访问次数:7587000
建立时间:2006年5月29日




[J2SE]JAAS:认证篇
软件技术

lhwork 发表于 2006/8/18 16:51:23

JAAS:认证篇基础: JAAS是JAVA安全中的重要部分. 一般谈到的Java安全包会涉及到JAAS,JCE,JSSE等. Java Authentication and Authorization Service (JAAS): A framework for user-based authentication Java Cryptography Extension (JCE): A framework for using strong ciphers on a global basis Java Secure Socket Extension (JSSE): An extension for SSL and Transport Layer Security (TLS) support JAAS 中几个比较常见的 classes http://java.sun.com/j2se/1.4.2/docs/guide/security/jaas/JAASRefGuide.html 普通对象 Subject Principals Credentials 身份验证相关的对象 LoginContext LoginModule CallbackHandler Callback 权限管控相关的对象 Policy AuthPermission PrivateCredentialPermission 跟认证有关系的主要是:普通对象 和身份验证相关的对象 .       Tomcat作为学习JAAS,不失为比较方便的web容器.       Tomcat有Realm的概念[参见Apache Tomcat官方网站].        Standard Realm Implementations JDBCRealmDataSourceRealmJNDIRealmMemoryRealmJAASRealm 所谓Realm是跟j2EE安全规范相关的,先介绍一下安全规范 Web层面.看下面的web.xml配置片段.  <security-constraint>    <web-resource-collection>      <web-resource-name>User Protected</web-resource-name>      <url-pattern>/protected/*</url-pattern>      <url-pattern>/protected.jsp</url-pattern>    </web-resource-collection>    <auth-constraint>       <role-name>*</role-name>    </auth-constraint>  </security-constraint>  <!--<login-config>    <auth-method>BASIC</auth-method>    <realm-name>MyJAASRealm</realm-name>  </login-config>-->  <!-- Default login configuration uses form-based authentication -->  <login-config>      <auth-method>FORM</auth-method>      <realm-name>Anonymous Form-Based Authentication Area</realm-name>      <form-login-config>        <form-login-page>/protected/login.jsp</form-login-page>        <form-error-page>/protected/error.jsp</form-error-page>      </form-login-config>  </login-config>           <!-- Security roles referenced by this web application -->  <security-role>     <role-name>*</role-name>  </security-role>  其中:具体说明可参见Servlet与JSP权威指南(More Servlets and Java Server Pages)一书,有乐于助人将第五章公布于网上,也可参见第9节[提供安全性],此处不再赘述. 在Tomcat中,Realm将对页面提交后的登录进行后续工作,也就是说你的user,role的关系可以存在于配置文件,数据库,LDAP[通过JNDI来配置].而选择的方法可以是 JDBCRealmDataSourceRealmJNDIRealmMemoryRealmJAASRealm 使用JAASRealm,很简单>  步骤一:  实现LoginModule. package cn.com.tiansky.auth.LoginModule; import java.io.IOException;import java.sql.Connection;import java.sql.ResultSet;import java.sql.Statement;import java.util.Map; import javax.naming.Context;import javax.naming.InitialContext;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 javax.sql.DataSource;import org.apache.log4j.Logger;import cn.com.tiansky.auth.Principal.Operator;import cn.com.tiansky.tool.MD5; /** * MySampleModule,A sample LoginModule *  * @author tiansky * @version 1.0 */public class MySampleModule implements LoginModule {  private Subject _subject;  private CallbackHandler _ch;  private Map _sharedState;  private Map _options;  private String _jndi;  private Operator _op = null;  private String _mark;  private String username;  private String password;  private static Logger log = Logger.getLogger(MySampleModule.class);  private boolean _debug = false;  /**  * @param arg0  * @param arg1  * @param arg2  * @param arg3  */ public void initialize(Subject arg0, CallbackHandler arg1, Map arg2,   Map arg3) {  this._subject = arg0;  this._ch = arg1;  this._sharedState = arg2;  this._options = arg3;  if (_options.containsKey("jndi")) {   _jndi = (String) _options.get("jndi");  }  if (_options.containsKey("mark")) {   _mark = ((String) _options.get("mark"));  }  if (_options.containsKey("debug")) {   _debug = "true".equalsIgnoreCase((String) _options.get("debug"));  } }  public boolean login() throws LoginException {   if (_ch == null)   throw new LoginException("获取认证信息的CallbackHandler为空,无法获取认证信息");   Callback[] callbacks = new Callback[2];  callbacks[0] = new NameCallback("userid: ");  callbacks[1] = new PasswordCallback("password: ",false);  log.info("开始获取认证信息...");  try {    _ch.handle(callbacks);   username = ((NameCallback) callbacks[0]).getName();   // new String(latin.getBytes("iso-8859-1"),"gbk");   log.debug("转码"+username);   final char[] passwordcontents;   passwordcontents = ((PasswordCallback) callbacks[1]).getPassword();   password = new String(passwordcontents);   if (_debug) {    log.debug("[username]=" + username);    log.debug("[password]=" + password);   }    if (password == null) {    password = "";   }    if ("PLAIN".equals(_mark)) {    ;// do nothing   } else if ("MD5".equals(_mark)) {    try {     password = MD5.encrypt(password);     log.debug("md5password" + password);    } catch (Exception e) {     log.warn("MD5加密出错", e);     throw new LoginException("MD5加密出错");    }    } else if ("DES".equals(_mark)) {    ;// add some des encrypt process   } else {    throw new LoginException("无法识别的加密算法:" + _mark);   }    if (_debug) {    log.debug("[password(after encrypt)]=" + password);   }    //((PasswordWebCallback) callbacks[1]).clearPassword();   } catch (UnsupportedCallbackException uce) {   throw new LoginException("未知的callback类型: "     + uce.getCallback().toString());  } catch (IOException e) {   throw new LoginException("未知的IO错误.");  }  try  {   if(checkuser(username,password)==1)   {    log.info("成功获得登录信息");    return true;   }   else   {    log.error("帐号或密码错误");   }     }  catch(Exception e)  {   log.error("查询帐号[数据库操作异常]",e);   throw new LoginException("查询帐号[数据库操作异常].");  }  return false; }  public boolean logout() throws LoginException {   _subject.getPrincipals().clear();  return true; }  public boolean abort() throws LoginException {   log.info("放弃登录.");  logout();  return true; }  public boolean commit() throws LoginException {      _subject.getPrincipals().add(_op);    if (_debug)          {              log.info("用户所属组:" + _subject.getPrincipals());          }           // in any case, clean out state          username = null;          password = null;          log.info("授权成功.");  return true; }  private int checkuser(String user, String pwd) throws Exception {  int rei = 0;  // Obtain our environment naming context  log.debug("Obtain our environment naming context");  Context initCtx = new InitialContext();  Context envCtx = (Context) initCtx.lookup("java:comp/env");   // Look up our data source  DataSource ds = (DataSource) envCtx.lookup(this._jndi);  log.debug("获取ds成功!");  // Allocate and use a connection from the pool  Connection conn = ds.getConnection();  log.debug("获取conn成功!");  // ... use this connection to access the database ...  String sql = "select OPERATORID from operator where OPERATORLOGINNAME='"    + user + "' and OPERATORPASSWORD='" + pwd + "' ";  log.debug("sql!= "+sql);  Statement st = conn.createStatement();  ResultSet rs = st.executeQuery(sql);  if (rs.next()) {   String oid = rs.getString("OPERATORID");   _op = new Operator(oid);   _op.setName("操作员");   _op.setLoginname(user);   _op.setPwd(pwd);   rei = 1;  } else {   System.out.println("帐号不存在或密码错误!");  }  conn.close();  return rei;  }}


阅读全文(2446) | 回复(0) | 编辑 | 精华
 



发表评论:
昵称:
密码:
主页:
标题:
验证码:  (不区分大小写,请仔细填写,输错需重写评论内容!)



站点首页 | 联系我们 | 博客注册 | 博客登陆

Sponsored By W3CHINA
W3CHINA Blog 0.8 Processed in 0.063 second(s), page refreshed 144754958 times.
《全国人大常委会关于维护互联网安全的决定》  《计算机信息网络国际联网安全保护管理办法》
苏ICP备05006046号