acegi security實踐教程—定製userDetailsService

  前面我們都是使用默認的UserDetailsService,無論是使用InMemoryDaoImpl還是JdbcDaoImpl這種形式。那這篇文章給大家講解如何自定義userDetailsService,正如咱們前面寫過自己的logoutFilter類。

  源碼講解

  UserDetailsService是個對用戶信息操作的接口,其中只有一個方法UserDetails loadUserByUsername(String username),若自定義userDetailsService則需要實現acegi中的userDetailsService接口,實現此方法即可。
  package org.acegisecurity.userdetails;
  import org.springframework.dao.DataAccessException;
  public abstract interface UserDetailsService
 {
    public abstract UserDetails loadUserByUsername(String paramString)
    throws UsernameNotFoundException, DataAccessException;
  }


  另外,此方法返回的UserDetails也是接口,acegi中實現其接口的類是User,所以若自定義返回結果,也須實現acegi中的UserDetails接口。
package org.acegisecurity.userdetails;
import java.io.Serializable;
import org.acegisecurity.GrantedAuthority;
public abstract interface UserDetails extends Serializable
{
  public abstract GrantedAuthority[] getAuthorities();
  public abstract String getPassword();
  public abstract String getUsername();
  public abstract boolean isAccountNonExpired();
  public abstract boolean isAccountNonLocked();
  public abstract boolean isCredentialsNonExpired();
  public abstract boolean isEnabled();
}

  開發步驟:

  開發環境:

MyEclispe10.7.1+tomcat6.0.37+acegi1.0.5+spring2.0+oracle10g+dbcp數據源

  項目目錄如下:  

  其中readme主要用來記錄本次驗證目的

  代碼關鍵:

  jdbcTemplate.queryForList返回的map類型的List,其中map的key值默認是數據庫列名。
  實現UserDetail中的GrantedAuthority[] authorities 是個接口形式,主要存放權限信息。獲取的list對象轉化成數組對象如下:
for(int i=0;i<dbAuths.size();i++){
String auth=(String)dbAuths.get(i).get("AUTHS");
GrantedAuthorityImpl authority = new GrantedAuthorityImpl(auth);
listAuth.add(authority);
}
GrantedAuthority[] arrayAuths = (GrantedAuthority[]) listAuth.toArray(new GrantedAuthority[listAuth.size()]);

  另外注意:實現UserDetail類中方法,默認爲false,根據實際情況而定,若不做處理,可以設置爲true。
   public boolean isAccountNonExpired() {
// TODO Auto-generated method stub
return true;
}
@Override
public boolean isAccountNonLocked() {
// TODO Auto-generated method stub
return true;
}
@Override
public boolean isCredentialsNonExpired() {
// TODO Auto-generated method stub
return true;
}
@Override
public boolean isEnabled() {
// TODO Auto-generated method stub
if("1".equals(enabled)){
return true;
}else{
return false;
}
}

  定製類:

package com.extend;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.acegisecurity.GrantedAuthority;
import org.acegisecurity.GrantedAuthorityImpl;
import org.acegisecurity.userdetails.User;
import org.acegisecurity.userdetails.UserDetails;
import org.acegisecurity.userdetails.UserDetailsService;
import org.acegisecurity.userdetails.UsernameNotFoundException;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.JdbcTemplate;

public class MyUserDetailService implements UserDetailsService {

	 private JdbcTemplate jdbcTemplate;
	@Override
	public UserDetails loadUserByUsername(String username)
			throws UsernameNotFoundException, DataAccessException {
		//根據用戶名查詢用戶基本信息
		String baseSql="select * from test_user t where t.user_name=?";
		List<Map> list=this.jdbcTemplate.queryForList(baseSql,new Object[]{username});
		if(list.size()==0){
			throw new UsernameNotFoundException("User not Found");
		}
		Map pMap=(Map)list.get(0);
		MyUser myUser=new MyUser();
		myUser.setUsername((String)pMap.get("USER_NAME"));
		myUser.setPassword((String)pMap.get("PWD"));
		myUser.setEnabled((String)pMap.get("ENABLED"));
		//根據用戶名查詢用戶權限信息
		String authSql="select AUTHS from test_auths t where t.user_name=?";
		List<Map> dbAuths=this.jdbcTemplate.queryForList(authSql,new Object[]{username});
		if(dbAuths.size()==0){
			throw new UsernameNotFoundException("User has no GrantAuthority");
		}
		List listAuth=new ArrayList();
		for(int i=0;i<dbAuths.size();i++){
			String auth=(String)dbAuths.get(i).get("AUTHS");
			GrantedAuthorityImpl authority = new GrantedAuthorityImpl(auth);
			listAuth.add(authority);
		}
    	GrantedAuthority[] arrayAuths = (GrantedAuthority[]) listAuth.toArray(new GrantedAuthority[listAuth.size()]);
		myUser.setAuthorities(arrayAuths);
		return myUser;
	}
	public JdbcTemplate getJdbcTemplate() {
		return jdbcTemplate;
	}
	public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
		this.jdbcTemplate = jdbcTemplate;
	}

}
package com.extend;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.acegisecurity.GrantedAuthority;
import org.acegisecurity.GrantedAuthorityImpl;
import org.acegisecurity.userdetails.User;
import org.acegisecurity.userdetails.UserDetails;
import org.acegisecurity.userdetails.UserDetailsService;
import org.acegisecurity.userdetails.UsernameNotFoundException;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.JdbcTemplate;

public class MyUserDetailService implements UserDetailsService {

	 private JdbcTemplate jdbcTemplate;
	@Override
	public UserDetails loadUserByUsername(String username)
			throws UsernameNotFoundException, DataAccessException {
		//根據用戶名查詢用戶基本信息
		String baseSql="select * from test_user t where t.user_name=?";
		List<Map> list=this.jdbcTemplate.queryForList(baseSql,new Object[]{username});
		if(list.size()==0){
			throw new UsernameNotFoundException("User not Found");
		}
		Map pMap=(Map)list.get(0);
		MyUser myUser=new MyUser();
		myUser.setUsername((String)pMap.get("USER_NAME"));
		myUser.setPassword((String)pMap.get("PWD"));
		myUser.setEnabled((String)pMap.get("ENABLED"));
		//根據用戶名查詢用戶權限信息
		String authSql="select AUTHS from test_auths t where t.user_name=?";
		List<Map> dbAuths=this.jdbcTemplate.queryForList(authSql,new Object[]{username});
		if(dbAuths.size()==0){
			throw new UsernameNotFoundException("User has no GrantAuthority");
		}
		List listAuth=new ArrayList();
		for(int i=0;i<dbAuths.size();i++){
			String auth=(String)dbAuths.get(i).get("AUTHS");
			GrantedAuthorityImpl authority = new GrantedAuthorityImpl(auth);
			listAuth.add(authority);
		}
    	GrantedAuthority[] arrayAuths = (GrantedAuthority[]) listAuth.toArray(new GrantedAuthority[listAuth.size()]);
		myUser.setAuthorities(arrayAuths);
		return myUser;
	}
	public JdbcTemplate getJdbcTemplate() {
		return jdbcTemplate;
	}
	public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
		this.jdbcTemplate = jdbcTemplate;
	}

}

  acegi配置文件:

>    <!-- 從數據庫中讀取用戶信息驗證身份 -->
	<bean id="daoAuthenticationProvider"
		class="org.acegisecurity.providers.dao.DaoAuthenticationProvider">
		<property name="userDetailsService" ref="userDetailsService" />
	</bean>

    <!-- 把用戶信息、權限信息放到數據庫中-->
	<bean id="userDetailsService"
		class="com.extend.MyUserDetailService">
		<property name="jdbcTemplate" ref="JdbcTemplate"> </property>
	</bean>
	<bean id="JdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
	   <property name="dataSource" ref="dataSource"></property>
	</bean>
	<!-- 數據源的綁定 -->
    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"            
        destroy-method="close">            
	    <property name="driverClassName" value="oracle.jdbc.driver.OracleDriver" />           
	    <property name="url" value="jdbc:oracle:thin:@127.0.0.1:1521:orclnew" />           
	    <property name="username" value="drp"/>           
	    <property name="password" value="drp" />           
    </bean>

  debug流程:







  上述帶領大家進入debug調試,是爲了通過分析源碼進一步瞭解acegi的調用流程。

 項目下載:

 
  
   
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章