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):

Xml代码 复制代码
  1. Sample   
  2. {   
  3.   com.fastunit.samples.jaas.SampleLoginModule required debug=false;   
  4. };  
Sample
{
  com.fastunit.samples.jaas.SampleLoginModule required debug=false;
};

 

此文件定义了一个“Sample”验证模块,使用SampleLoginModule来进行验证。

 

2. 启用配置文件:
-Djava.security.auth.login.config=D:/jaas.conf

 

二、客户端调用

Java代码 复制代码
  1. package javaapplication3;   
  2.   
  3. import javax.security.auth.login.LoginContext;   
  4. import javax.security.auth.login.LoginException;   
  5.   
  6. /**  
  7.  *  
  8.  * @author Dao  
  9.  */  
  10. public class LoginManager    
  11. {   
  12.      
  13.   
  14.   public LoginManager()   
  15.   {   
  16.        
  17.   }   
  18.      
  19.   public static void main(String[] args)   
  20.   {   
  21.     try  
  22.     {   
  23.       String username = "username";   
  24.       String password = "password";   
  25.          
  26.       //此处指定了使用配置文件的“Sample"验证模块,对应的实现类为SampleLoginModule   
  27.       LoginContext lc = new LoginContext("Sample"new SampleCallbackHandler(username, password));   
  28.          
  29.       //进行登录操作,如果验证失败会抛出异常   
  30.       lc.login();   
  31.     }   
  32.     catch (LoginException e)   
  33.     {   
  34.       e.printStackTrace();   
  35.     }   
  36.     catch (SecurityException e)   
  37.     {   
  38.       e.printStackTrace();   
  39.     }   
  40.   }   
  41. }  
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();
    }
  }
}

 

 

Java代码 复制代码
  1. package javaapplication3;   
  2.   
  3. import java.io.IOException;   
  4. import javax.security.auth.callback.Callback;   
  5. import javax.security.auth.callback.CallbackHandler;   
  6. import javax.security.auth.callback.NameCallback;   
  7. import javax.security.auth.callback.PasswordCallback;   
  8. import javax.security.auth.callback.UnsupportedCallbackException;   
  9.   
  10. /**  
  11.  *  
  12.  * @author Dao  
  13.  */  
  14. public class SampleCallbackHandler implements CallbackHandler   
  15. {   
  16.   private String username;   
  17.   private String password;   
  18.   
  19.   public SampleCallbackHandler(String username, String password)   
  20.   {   
  21.     this.username = username;   
  22.     this.password = password;   
  23.   }   
  24.   
  25.   public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException   
  26.   {   
  27.     for (int i = 0; i < callbacks.length; i++)   
  28.     {   
  29.       if (callbacks[i] instanceof NameCallback)   
  30.       {   
  31.         NameCallback ncb = (NameCallback) callbacks[i];   
  32.         ncb.setName(this.username);   
  33.       }   
  34.       else if (callbacks[i] instanceof PasswordCallback)   
  35.       {   
  36.         PasswordCallback pcb = (PasswordCallback) callbacks[i];   
  37.         pcb.setPassword(this.password.toCharArray());   
  38.       }   
  39.     }   
  40.   }   
  41. }  
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());
      }
    }
  }
}

 

三、验证实现

 

Java代码 复制代码
  1. package javaapplication3;   
  2.   
  3. import java.io.IOException;   
  4. import java.util.Map;   
  5. import javax.security.auth.Subject;   
  6. import javax.security.auth.callback.Callback;   
  7. import javax.security.auth.callback.CallbackHandler;   
  8. import javax.security.auth.callback.NameCallback;   
  9. import javax.security.auth.callback.PasswordCallback;   
  10. import javax.security.auth.callback.UnsupportedCallbackException;   
  11. import javax.security.auth.login.LoginException;   
  12. import javax.security.auth.spi.LoginModule;   
  13.   
  14. /**  
  15.  *  
  16.  * @author Dao  
  17.  */  
  18. public class SampleLoginModule implements LoginModule   
  19. {   
  20.   private boolean isAuthenticated = false;   
  21.   private CallbackHandler callbackHandler;   
  22.   private Subject subject;   
  23.   private SamplePrincipal principal;   
  24.   
  25.   public SampleLoginModule()   
  26.   {   
  27.        
  28.   }   
  29.   
  30.   public void initialize(Subject subject, CallbackHandler callbackHandler, Map<String, ?> sharedState, Map<String, ?> options)   
  31.   {   
  32.     this.subject = subject;   
  33.     this.callbackHandler = callbackHandler;   
  34.   }   
  35.   
  36.   public boolean login() throws LoginException   
  37.   {   
  38.     try  
  39.     {   
  40.       NameCallback nameCallback = new NameCallback("username");   
  41.       PasswordCallback passwordCallback = new PasswordCallback("password"false);   
  42.          
  43.       Callback[] calls = new Callback[]{nameCallback, passwordCallback};   
  44.          
  45.       this.callbackHandler.handle(calls);   
  46.          
  47.       //获得用户数据   
  48.       String username = nameCallback.getName();   
  49.       String password = String.valueOf(passwordCallback.getPassword());   
  50.          
  51.       //TODO验证,如:查询数据库、LDAP。。。   
  52.       if (true)  //此处省去了实际的验证逻辑,在此假设验证通过   
  53.       {   
  54.         this.principal = new SamplePrincipal(username);   
  55.            
  56.         this.isAuthenticated = true;   
  57.       }   
  58.       else  
  59.       {   
  60.         throw new LoginException("user or password is wrong");   
  61.       }   
  62.     }   
  63.     catch (IOException e)   
  64.     {   
  65.       throw new LoginException("no such user");   
  66.     }   
  67.     catch (UnsupportedCallbackException e)   
  68.     {   
  69.       throw new LoginException("login failure");   
  70.     }   
  71.        
  72.     return this.isAuthenticated;   
  73.   }   
  74.   
  75.   /**  
  76.    * 验证后处理,在Subject中加入用户对象  
  77.    * @return  
  78.    * @throws javax.security.auth.login.LoginException  
  79.    */  
  80.   public boolean commit() throws LoginException   
  81.   {   
  82.     if (this.isAuthenticated)   
  83.     {   
  84.       this.subject.getPrincipals().add(this.principal);   
  85.     }   
  86.     else  
  87.     {   
  88.       throw new LoginException("Authentication failure");   
  89.     }   
  90.        
  91.     return this.isAuthenticated;   
  92.   }   
  93.   
  94.   public boolean abort() throws LoginException   
  95.   {   
  96.     return false;   
  97.   }   
  98.   
  99.   public boolean logout() throws LoginException   
  100.   {   
  101.     this.subject.getPrincipals().remove(this.principal);   
  102.        
  103.     this.principal = null;   
  104.        
  105.     return true;   
  106.   }   
  107. }  
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;
  }
}

 

Java代码 复制代码
  1. package javaapplication3;   
  2.   
  3. import java.security.Principal;   
  4.   
  5. /**  
  6.  *  
  7.  * @author Dao  
  8.  */  
  9. public class SamplePrincipal implements Principal   
  10. {   
  11.   private String name;   
  12.   
  13.   public SamplePrincipal(String name)   
  14.   {   
  15.     this.name = name;   
  16.   }   
  17.   
  18.   public String getName()   
  19.   {   
  20.     return name;   
  21.   }   
  22.      
  23.   public boolean equals(Object ob)   
  24.   {   
  25.     if (ob instanceof SamplePrincipal)   
  26.     {   
  27.       SamplePrincipal principal = (SamplePrincipal) ob;   
  28.          
  29.       return this.name.equalsIgnoreCase(principal.getName());   
  30.     }   
  31.        
  32.     return false;   
  33.   }   
  34.      
  35.   public int hashCode()   
  36.   {   
  37.     return name.toUpperCase().hashCode();   
  38.   }   
  39. }  
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值