基于JAAS实现登录

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

 

package javaapplication3;

import java.security.Principal;

/**
 *
 * @author Dao
 */
public class SamplePrincipal implements Principal
{
  private String name;

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

  public String getName()
  {
    return name;
  }
  
  public boolean equals(Object ob)
  {
    if (ob instanceof SamplePrincipal)
    {
      SamplePrincipal principal = (SamplePrincipal) ob;
      
      return this.name.equalsIgnoreCase(principal.getName());
    }
    
    return false;
  }
  
  public int hashCode()
  {
    return name.toUpperCase().hashCode();
  }
}

 

你可能感兴趣的:(DAO,J2SE,Security,sun)