acegi security实践教程—定制userDetailsService
2014-03-18 08:58
513 查看
前面我们都是使用默认的UserDetailsService,无论是使用InMemoryDaoImpl还是JdbcDaoImpl这种形式。那这篇文章给大家讲解如何自定义userDetailsService,正如咱们前面写过自己的logoutFilter类。
另外,此方法返回的UserDetails也是接口,acegi中实现其接口的类是User,所以若自定义返回结果,也须实现acegi中的UserDetails接口。
![](https://img-blog.csdn.net/20140315154919968?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQveXVlYmluZ2hhb3l1YW4=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
实现UserDetail中的GrantedAuthority[] authorities 是个接口形式,主要存放权限信息。获取的list对象转化成数组对象如下:
另外注意:实现UserDetail类中方法,默认为false,根据实际情况而定,若不做处理,可以设置为true。
![](https://img-blog.csdn.net/20140315155547656?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQveXVlYmluZ2hhb3l1YW4=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
![](https://img-blog.csdn.net/20140315155601250?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQveXVlYmluZ2hhb3l1YW4=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
![](https://img-blog.csdn.net/20140315155619312?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQveXVlYmluZ2hhb3l1YW4=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
![](https://img-blog.csdn.net/20140315155633359?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQveXVlYmluZ2hhb3l1YW4=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
![](https://img-blog.csdn.net/20140315155650968?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQveXVlYmluZ2hhb3l1YW4=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
![](https://img-blog.csdn.net/20140315155701625?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQveXVlYmluZ2hhb3l1YW4=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
上述带领大家进入debug调试,是为了通过分析源码进一步了解acegi的调用流程。
源码讲解
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的调用流程。
项目下载:
相关文章推荐
- acegi security实践教程—简单定制logoutFilter
- acegi security实践教程—资源角色信息存到放数据库
- Spring Security 4.1.3 实现UserDetailsService,实现登陆验证、会话管理
- 基于数据库自定义UserDetailsService实现Spring security认证
- acegi security实践教程—form认证
- PreAuthenticatedGrantedAuthoritiesUserDetailsService/DelegatingFilterProxy
- 自定义 Spring Security 4 的UserDetailsService和UserDetails
- 简单继承UserDetailsService
- acegi security实践教程—访问系统中资源前必须登陆系统
- 详解Spring Security进阶身份认证之UserDetailsService(附源码)
- acegi security实践教程—basic认证
- SpringSecurity4使用UserDetailsService时无法注入数据库持久层的service、dao
- acegi security实践教程—form认证之debug调试
- spring security3.x学习(14)_关系型数据库使用的UserDetailsService(JdbcDaoImpl)
- acegi security实践教程—logoutFilter应用以及调试
- spring security3.x学习(14)_关系型数据库使用的UserDetailsService(JdbcDaoImpl)
- acegi security实践教程—basic认证之debug调试
- acegi security实践教程—由debug调试来解析session
- acegi security实践教程—把用户信息存放到数据库
- acegi security实践教程—入门