一、思路
二、加入SpringSecurity环境
web.xml:
创建配置类:
spring-web.mvc.xml:
考虑到权限控制系统更多的需要控制Web请求,而且有些请求没有经过Service方法,所以在SpringMVC的IOC容器中扫描SecurityConfig,但是SpringSecurity是有管理Service、Dao方法的能力的。
三、IOC容器加载问题
ContextLoaderListener初始化后,springSecurityFilterChain就在ContextLoaderListener创建的IOC容器中查找所需要的bean,但是我们没有在ContextLoaderListener的IOC容器中扫描SpringSecurity的配置类,所以springSecurityFilterChain对应的bean找不到。
web.xml:
首先加载ContextLoaderListener,接着加载springSecurityFilterChain——>IOC容器去查找springSecurityFilterChain的bean,找不到会抛,找到了再加载DispatcherServlet,DispatcherServlet再去扫描SecurityConfig所在的包,去创建springSecurityFilterChain的bean。
解决方法:
1、将ContextLoaderListener取消,原本由ContextLoaderListener读取的Spring配置文件交给DispatcherServlet负责读取。
四、发行首页和静态资源
五、前往登录页面
六、提交登录表单
修改表单登录链接:
去掉拦截器才能完成登录:
七、登录后显示用户名
include-nav.jsp:
<%@taglib uri="http://www.springframework.org/security/tags" prefix="security" %>
八、退出登录
九、登录页面显示提示消息的EL表达式
十、数据库登录
以上需要修改:
十一、封装从数据库查询的角色、权限信息
@Service
public class CrowdfundingUserDetailsService implements UserDetailsService {
@Autowired
private AdminMapper adminMapper;
@Autowired
private RoleMapper roleMapper;
@Autowired
private AuthMapper authMapper;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
AdminExample adminExample = new AdminExample();
//封装查询条件
adminExample.createCriteria().andLoginAcctEqualTo(username);
//执行查询
List<Admin> list = adminMapper.selectByExample(adminExample);
//检查list是否有效
if (!CrowdfundingUtils.collectionEffective(list)){
return null;
}
//从list取出Admin对象
Admin admin = list.get(0);
//获取密码
String userPswd = admin.getUserPswd();
//封装角色权限信息
//创建存储角色、权限信息集合
List<GrantedAuthority> authorities = new ArrayList<>();
Integer adminId = admin.getId();
//查询分配给当前Admin的角色
List<Role> roleList = roleMapper.selectAssignedRoleList(adminId);
for (Role role : roleList){
String roleName = "ROLE_" + role.getName();
//存入集合
authorities.add(new SimpleGrantedAuthority(roleName));
}
//封装权限信息
List<Auth> authList = authMapper.selectAuthListByAdminId(adminId);
for (Auth auth : authList){
//不加前缀
String authName = auth.getName();
authorities.add(new SimpleGrantedAuthority(authName));
}
//返回User对象
return new User(username,userPswd,authorities);
}
}
十二、封装SecurityAdmin扩展User
十三、使用BCryptPasswordEncoder加密
十四、使用antMatcher注解控制权限
十五、使用标签控制页面元素显示
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<%@taglib uri="http://www.springframework.org/security/tags" prefix="security"%>
<html lang="UTF-8">
<%@include file="/WEB-INF/include-head.jsp"%>
<body>
<%@include file="/WEB-INF/include-nav.jsp"%>
<div class="container-fluid">
<div class="row">
<%@include file="/WEB-INF/include-sidebar.jsp"%>
<div class="col-sm-9 col-sm-offset-3 col-md-10 col-md-offset-2 main">
<h1 class="page-header">控制面板</h1>
<div class="row placeholders">
<security:authorize access="hasRole('剑主')">
<div class="col-xs-6 col-sm-3 placeholder">
<img data-src="holder.js/200x200/auto/sky" class="img-responsive" alt="Generic placeholder thumbnail">
<h4>Label[剑主]</h4>
<span class="text-muted">Something else</span>
</div>
</security:authorize>
<security:authorize access="hasAuthority('user:get')">
<div class="col-xs-6 col-sm-3 placeholder">
<img data-src="holder.js/200x200/auto/vine" class="img-responsive" alt="Generic placeholder thumbnail">
<h4>Label[user:get]</h4>
<span class="text-muted">Something else</span>
</div>
</security:authorize>
<security:authorize access="hasRole('剑主')">
<div class="col-xs-6 col-sm-3 placeholder">
<img data-src="holder.js/200x200/auto/sky" class="img-responsive" alt="Generic placeholder thumbnail">
<h4>Label</h4>
<span class="text-muted">Something else</span>
</div>
</security:authorize>
<security:authorize access="hasRole('剑主')">
<div class="col-xs-6 col-sm-3 placeholder">
<img data-src="holder.js/200x200/auto/vine" class="img-responsive" alt="Generic placeholder thumbnail">
<h4>Label</h4>
<span class="text-muted">Something else</span>
</div>
</security:authorize>
</div>
</div>
</div>
</div>
</body>
</html>