目标:实现Spring Boot集成shiro权限认证框架 工具:IDEA--2020.1 学习目标:实现Spring Boot集成shiro权限认证框架 本次学习的工程有点多,需要就请联系作者!
<!-- shiro依赖配置 -->
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>1.4.0</version>
</dependency>
package com.xmaven.form;
import org.apache.shiro.web.filter.authc.FormAuthenticationFilter;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
public class CustomFormAuthenticationFilter extends FormAuthenticationFilter {
@Override
protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception {
HttpServletRequest req=(HttpServletRequest) request;
String code1 = req.getParameter("randomcode");
System.out.println("用户输入的验证码:"+code1);
String code2 = (String) req.getSession().getAttribute("validateCode");
System.out.println("系统生成的验证码是:"+code2);
if(code1==null||code2==null) {
req.setAttribute(FormAuthenticationFilter.DEFAULT_ERROR_KEY_ATTRIBUTE_NAME,"randomCodeError");
return true;
}else {
if(!code1.equals(code2)) {
req.setAttribute(FormAuthenticationFilter.DEFAULT_ERROR_KEY_ATTRIBUTE_NAME,"randomCodeError");
return true;
}
}
return super.onAccessDenied(request, response);
}
}
public class CustomRealmMD5 extends AuthorizingRealm {
@Autowired
SysUserService sysUserService;
@Autowired
SysPermissionService sysPermissionService;
//用户授权
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection arg0) {
SysUser sysUser = (SysUser) arg0.getPrimaryPrincipal();
System.out.println("当前被认证的用户是:"+sysUser.getUsername());
//从数据库查询改用户拥有哪些权限
List<String> list = new ArrayList<String>();
List<SysPermission> perms = sysPermissionService.getPercodeByUsercode(sysUser.getUsercode());
if (perms!=null&&perms.size()>0) {
System.out.println("该用户拥有以下权限:");
for (SysPermission perm : perms) {
String code = perm.getPercode();
if(code!=null&&!code.equals("")) {
System.out.println("========================="+code);
list.add(code);//把权限源添加到list集合
}
}
}
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
info.addStringPermissions(list);
return info;
}
//用户认证
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
String username = (String) token.getPrincipal();
System.out.println("当前被认证的用户是:"+username);
//1.需要从数据库查询是否有该用户
SysUser sysUser = sysUserService.login(username);
if(sysUser == null) {
System.out.println("不存在此用户");
}
//2.该用户的密码
String password = sysUser.getPassword();
String salt = sysUser.getSalt();
//第一个参数可以是任意类型object
SimpleAuthenticationInfo info =new SimpleAuthenticationInfo(sysUser, password,ByteSource.Util.bytes(salt), super.getName());
return info;
}
}
@Configuration //配置类
public class ShiroConfig {
@Autowired
SysPermissionService sysPermissionService;
//MD5方法解析密码
@Bean
public CustomRealmMD5 customRealmMD5() {
CustomRealmMD5 realm = new CustomRealmMD5();
HashedCredentialsMatcher matcher = new HashedCredentialsMatcher();
matcher.setHashAlgorithmName("md5");
matcher.setHashIterations(3);
realm.setCredentialsMatcher(matcher);
return realm;
}
//安全管理器
@Bean
public SecurityManager securityManager() {
DefaultWebSecurityManager manager = new DefaultWebSecurityManager();
//设置加密认证
manager.setRealm(this.customRealmMD5());
return manager;
}
//Shiro过滤器
@Bean("shiroFilter")
public ShiroFilterFactoryBean shiroFilter() {
//1.如果实现了验证码,该类名需要更换成自定义表单认证过滤器
//FormAuthenticationFilter form = new FormAuthenticationFilter();
//2.自定义表单认证过滤器(使用的是jsp验证码)
//CustomFormAuthenticationFilter form = new CustomFormAuthenticationFilter();
//3.使用的是kaptcha验证码生成器更加稳定
CaptchaValidateFilter form = new CaptchaValidateFilter();
form.setLoginUrl("/loginctrl/login.do");
form.setUsernameParam("uname");
form.setPasswordParam("upass");
ShiroFilterFactoryBean shiroFilter = new ShiroFilterFactoryBean();
shiroFilter.setSecurityManager(this.securityManager());
shiroFilter.setLoginUrl("/login.jsp");
shiroFilter.setSuccessUrl("/loginctrl/main.do");
shiroFilter.setUnauthorizedUrl("/nopermission.jsp");
LogoutFilter logout = new LogoutFilter();
logout.setRedirectUrl("/login.jsp");
Map<String, Filter> filters = new HashMap<String, Filter>();
filters.put("authc", form);
filters.put("logout", logout);
shiroFilter.setFilters(filters);
Map<String, String> map = new LinkedHashMap<String, String>();
//anon:可匿名访问,authc:需要认证才能访问
map.put("/css/**", "anon");
map.put("/images/**", "anon");
map.put("/js/**", "anon");
map.put("/sql/**", "anon");
map.put("/upload/**", "anon");
map.put("/login.jsp", "anon");
map.put("/login2.jsp", "anon");
map.put("/main.jsp", "anon");
map.put("/index.jsp", "anon");
map.put("/captcha/**", "anon");
//登出,退出登录
map.put("/logout.do", "logout");
map.put("/validatecode.jsp", "anon");
//权限设置(从权限表查询所有的权限并且设置)
List<SysPermission> list = sysPermissionService.getAllPermissions();
if (list!=null&&list.size()>0) {
System.out.println("所有权限并设置:");
for (SysPermission perm : list) {
String url = perm.getUrl();
String code = perm.getPercode();
if(code!=null&&!code.equals("")&&url!=null&&!url.equals("")) {
System.out.println("=====url======="+url+"========code====="+code);
map.put(url, "perms["+code+"]");
}
}
}
// user指的是用户认证通过或者配置了Remember Me记住用户登录状态后可访问
map.put("/**", "authc");
shiroFilter.setFilterChainDefinitionMap(map);
return shiroFilter;
}
}
//把该类注册成bean对象,并且作为控制器组件
@Controller
//给该类配置一个请求映射的url地址
@RequestMapping("/loginctrl")
public class LoginController {
//登陆失败的方法
@RequestMapping("/login.do")
public ModelAndView login(ModelAndView mav,HttpServletRequest req) {
System.out.println("用户认证失败");
//通过认证失败的属性名称获取对应的值
String msg = (String) req.getAttribute(FormAuthenticationFilter.DEFAULT_ERROR_KEY_ATTRIBUTE_NAME);
System.out.println("认证失败的消息:"+msg);
String fail = "";
if (msg!=null) {
if (msg.equals(UnknownAccountException.class.getName())) {
fail = "unknown";//账户不存在
}else if (msg.equals(IncorrectCredentialsException.class.getName())) {
fail = "error";
}else if (msg.equals("randomCodeError")) {
fail = "code";
}else {
fail = "other";
}
}
mav.setViewName("redirect:../login.jsp?isfail="+fail);
return mav;
}
@RequestMapping("/main.do")
public ModelAndView main(ModelAndView mav,HttpSession session,String rememberMe) {
System.out.println("用户认证成功");
Subject subject = SecurityUtils.getSubject();
SysUser sysUser = (SysUser) subject.getPrincipal();
session.setAttribute("nowuser", sysUser);
mav.setViewName("redirect:../main.jsp");
return mav;
}
}
本次工作包括知识过多,需要请联系作者,谢谢合作!