基于JAAS实现登录

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();
  }

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值