Java快速开发平台

www.fastunit.com

  BlogJava :: 首页 :: 联系 :: 聚合  :: 管理
  23 Posts :: 0 Stories :: 273 Comments :: 0 Trackbacks

JAAS:Java Authentication and Authorization Service,提供了认证和授权框架。

本例是认证的实现,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

二、客户端调用

import javax.security.auth.login.LoginContext;
import javax.security.auth.login.LoginException;
import javax.servlet.http.HttpServletRequest;

public class LoginManager {

  
public static boolean login(HttpServletRequest request) {
    
try {
      String username 
= request.getParameter("username");
      String password 
= request.getParameter("password");
      
//此处指定了使用配置文件的“Sample”验证模块,对应的实现类为SampleLoginModule
      LoginContext lc = new LoginContext("Sample"new SampleCallbackHandler(
          username, password));
      lc.login();
// 如果验证失败会抛出异常
      return true;
    } 
catch (LoginException e) {
      e.printStackTrace();
      
return false;
    } 
catch (SecurityException e) {
      e.printStackTrace();
      
return false;
    }
  }

}

 

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;

public class SampleCallbackHandler implements CallbackHandler {
  
private String username;
  
private String password;

  
public SampleCallbackHandler(final String username, final String password) {
    
this.username = username;
    
this.password = password;
  }

  
public void handle(Callback[] callbacks) throws IOException,
      UnsupportedCallbackException {
    
for (int index = 0; index < callbacks.length; index++) {
      
if (callbacks[index] instanceof NameCallback) {
        NameCallback ncb 
= (NameCallback) callbacks[index];
        ncb.setName(username);
      }
      
if (callbacks[index] instanceof PasswordCallback) {
        PasswordCallback pcb 
= (PasswordCallback) callbacks[index];
        pcb.setPassword(password.toCharArray());
      }
    }
  }
}

三、验证实现

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;

public class SampleLoginModule implements LoginModule {
  
private boolean isAuthenticated = false;
  
private CallbackHandler callbackHandler;
  
private Subject subject;
  
private SamplePrincipal principal;

  
public void initialize(Subject subject, CallbackHandler callbackHandler,
      Map sharedState, Map options) {
    
this.subject = subject;
    
this.callbackHandler = callbackHandler;
  }

  
public boolean login() throws LoginException {
    
try {
      NameCallback nameCallback 
= new NameCallback("username");
      PasswordCallback passwordCallback 
= new PasswordCallback("password",
          
false);
      
final Callback[] calls = new Callback[] { nameCallback, passwordCallback };

      
// 获取用户数据
      callbackHandler.handle(calls);
      String username 
= nameCallback.getName();
      String password 
= String.valueOf(passwordCallback.getPassword());

      
// TODO 验证,如:查询数据库、LDAP。。。

      
if (true) {// 验证通过
        principal = new SamplePrincipal(username);
        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 isAuthenticated;
  }

  
/**
   * 验证后的处理,在Subject中加入用户对象
   
*/
  
public boolean commit() throws LoginException {
    
if (isAuthenticated) {
      subject.getPrincipals().add(principal);
    } 
else {
      
throw new LoginException("Authentication failure");
    }
    
return isAuthenticated;
  }

  
public boolean abort() throws LoginException {
    
return false;
  }

  
public boolean logout() throws LoginException {
    subject.getPrincipals().remove(principal);
    principal 
= null;
    
return true;
  }
}

 


import java.security.Principal;

public final class SamplePrincipal implements Principal {

  
private String name;

  
public SamplePrincipal(String name) {
    
this.name = name;
  }

  
public String getName() {
    
return name;
  }

  
public boolean equals(Object o) {
    
return (o instanceof SamplePrincipal)
        
&& this.name.equalsIgnoreCase(((SamplePrincipal) o).name);
  }

  
public int hashCode() {
    
return name.toUpperCase().hashCode();
  }

}
posted on 2008-01-28 16:12 FastUnit 阅读(20297) 评论(11)  编辑  收藏 所属分类: Java

Feedback

# re: 基于JAAS实现登录 2008-01-28 21:26 BeanSoft
收藏 支持了!  回复  更多评论
  

# re: 基于JAAS实现登录 2008-01-30 09:09 loocky
一般来说不用编程的方式来通过JAAS 实现权限设置,可以用可配置方式来实现,你可以看看SERVLET EJB都有对JAAS的可配置的方式的支持 ,非常方便  回复  更多评论
  

# re: 基于JAAS实现登录 2008-02-14 13:37 FastUnit
@loocky
承教。  回复  更多评论
  

# re: 基于JAAS实现登录 2009-02-08 00:24 YinPSoft
比较清晰,有参考价值  回复  更多评论
  

# re: 基于JAAS实现登录 2009-05-23 19:15 steeven
loginModule是给个session一个实例吗?
如果在多线程环境下,成员变量在pricipal在commit()的时候可能已经变掉了  回复  更多评论
  

# re: 基于JAAS实现登录 2009-06-06 10:54 lao
好东西!  回复  更多评论
  

# re: 基于JAAS实现登录 2009-08-30 17:59 jaas
似乎jaas没什么实用价值  回复  更多评论
  

# re: 基于JAAS实现登录[未登录] 2009-08-31 15:13 steeven
jboss安全的基石啊  回复  更多评论
  

# re: 基于JAAS实现登录 2010-06-10 15:57 zone
http://java.sun.com/j2se/1.4.2/docs/guide/security/jaas/tutorials/GeneralAcnAndAzn.html#RunAzn  回复  更多评论
  

# re: 基于JAAS实现登录 2010-08-26 14:32 啊啊啊
先圣先师   回复  更多评论
  

# re: 基于JAAS实现登录[未登录] 2014-12-04 16:51 Abc
抄来的吧?  回复  更多评论
  


只有注册用户登录后才能发表评论。


网站导航: