之前给出的用户名和密码的信息都是由用户固定填写的,这种做法并不适合实际的开发,所以在所有项目系统中,用户名和密码都应该交由数据库进行管理,包括密码也应该使用MD5进行加密处理。
一、基于标准数据库的保存
如果要想实现基于标准的数据库保存操作,那么首先要根据Spring安全框架的定义要求,创建相关的数据表。
一个用户具备多个角色,所以属于一对多的关系。
如果现在要想使用MD5的加密处理,需要一个密码的编码器操作,专门的接口:
修改applicationContext,xml文件:
但是用户数据表上本身是存在有一个启用标记的,只有启动标记为非0的时候才可以使用,一般使用1.
如果改成0,就不能登录了,主要的原因是因为用户被锁定了,所以现在可以针对状态进行提示。
修改login.jsp页面:
spring安全框架的控制实际上是比较麻烦的,尤其是错误信息的输出上。
二、基于非数据库的保存
使用的标准数据库表名名称都要求是固定的,这在很多情况下有一些人是不能够认可的。
所以在设计的时候,也可以非标准数据库完成。
随后处理配置文件:
修改applicationContext,xml文件:
即使定义了不一样的表名称和字段名称,也需要遵从spring的固定安排,否则无法实现。
三、UserDetails接口
如果给出的表结构就不是这种定义的结构呢?
所以在Spring Security里面专门提供给用户可以自己实现登录验证查询的操作接口。
在整个spring安全框架之中,只提供有一个UserDetailService接口给用户自己实现登录操作。
但是由于登录是需要数据库功能支持的,那么本次使用JdbcTemplate实现登录检查。
修改applicationContext,xml文件:
范例:定义UserDetailService接口子类,并且注入以上对象
package jcn;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Component;
@Component
public class UserDetailsImpl implements UserDetailsService {
private JdbcTemplate jdbcTemplate;
@Override
public UserDetails loadUserByUsername(final String mid)
throws UsernameNotFoundException {
String sql = "SELECT mid ,password,enabeld FORM member WHERE mid=?";
UserDetails details = this.jdbcTemplate.queryForObject(sql, new RowMapper<UserDetails>(){
@Override
public UserDetails mapRow(ResultSet rs, int row)
throws SQLException {
//当查询完数据之后,表示用户名称存在,但是还没有角色
String sql2 = "SELECT title FROM role WHERE mid=?";
//查询出一个用户所具备的所有角色名称
List<String> titleStrings = UserDetailsImpl.this.jdbcTemplate.queryForList(sql2,String.class,mid);
//在spring安全框架之中必须将角色传递给指定的类型
List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
Iterator<String> iterator = titleStrings.iterator();
while (iterator.hasNext()) {
authorities.add(new SimpleGrantedAuthority(iterator.next()));//实例化GrantedAuthority
}
//最终的结果所有的用户数据和权限信息需要保存在UserDetail接口对象里
return new User(rs.getString(1),rs.getString(2),rs.getInt(3) == 1,true,true,true,authorities);
}
},mid);
if (details == null) {
throw new UsernameNotFoundException(mid + "该用户信息不存在");
}
return details;
}
}
在一些更为复杂的登录逻辑上,往往会根据角色找到权限组,以及根据权限组找到所有的权限信息。
修改applicationContext,xml文件:
此时就表示在当前的用户权限管理过程之中,就使用自定义的UserDetailService服务。