SpringBoot集成Shiro安全框架
跟着我的步骤:先运行起来再说
Spring集成Shiro的GitHub:https://github.com/yueshutong/shiro-imooc
一:导包
<!-- Shiro安全框架 -->
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-core</artifactId>
<version>1.4.0</version>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-web</artifactId>
<version>1.4.0</version>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>1.4.0</version>
</dependency>
二:ShiroConfig配置
import cn.zyzpp.shiro.CustomRealm;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.spring.LifecycleBeanPostProcessor;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.CookieRememberMeManager;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.apache.shiro.web.servlet.SimpleCookie;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.LinkedHashMap;
import java.util.Map;
/**
* Create by yster@foxmail.com 2018/5/17/017 20:18
*/
@Configuration
public class ShiroConfig {
/**
* 记住我:自动登录-1
*/
@Bean
public SimpleCookie getSimpleCookie(){
SimpleCookie simpleCookie = new SimpleCookie();
simpleCookie.setName("rememberMe");
simpleCookie.setMaxAge(20000000);
return simpleCookie;
}
/**
* 记住我:自动登录-2
*/
@Bean
public CookieRememberMeManager getCookieRememberMeManager(){
CookieRememberMeManager cookieRememberMeManager = new CookieRememberMeManager();
cookieRememberMeManager.setCookie(getSimpleCookie());
return cookieRememberMeManager;
}
/**
* 开启MD5加密
* @return
*/
@Bean
public HashedCredentialsMatcher getMatcher(){
HashedCredentialsMatcher matcher = new HashedCredentialsMatcher();
matcher.setHashAlgorithmName("md5");
matcher.setHashIterations(1);
return matcher;
}
/**
* 自定义Realm密码验证与加密
* @return
*/
@Bean
public CustomRealm getCustomRealm(){
CustomRealm customRealm = new CustomRealm();
customRealm.setCredentialsMatcher(getMatcher());
return customRealm;
}
/**
* 创建SecurityManager环境
* @return
*/
@Bean
public DefaultWebSecurityManager getSecurityManager(){
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
securityManager.setRealm(getCustomRealm());
securityManager.setRememberMeManager(getCookieRememberMeManager());
return securityManager;
}
/**
* Shiro在Web项目中的过滤
* @return
*/
@Bean
public ShiroFilterFactoryBean getfilterFactoryBean(){
ShiroFilterFactoryBean filterFactoryBean = new ShiroFilterFactoryBean();
filterFactoryBean.setSecurityManager(getSecurityManager());
/**
* 只有在下面配置路径访问权限,Shiro才会执行自动跳转。
* 如果使用Shiro注解权限,就只会报异常,
* 就只能采用统一异常处理的方法。
*/
//拦截器.
Map<String,String> filterChainDefinitionMap = new LinkedHashMap<String,String>();
// 配置不会被拦截的链接 顺序判断
filterChainDefinitionMap.put("/static/**", "anon");
//配置退出 过滤器,其中的具体的退出代码Shiro已经替我们实现了
filterChainDefinitionMap.put("/user/exit", "logout");
//<!-- 过滤链定义,从上向下顺序执行,一般将/**放在最为下边 -->:这是一个坑呢,一不小心代码就不好使了;
//<!-- authc:所有url都必须认证通过才可以访问; anon:所有url都都可以匿名访问-->
filterChainDefinitionMap.put("/user/user", "authc");
// 如果不设置默认会自动寻找Web工程根目录下的"/login.jsp"页面
filterFactoryBean.setLoginUrl("/user/login");
// 登录成功后要跳转的链接
filterFactoryBean.setSuccessUrl("/");
//未授权界面;
filterFactoryBean.setUnauthorizedUrl("/user/login");
filterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
return filterFactoryBean;
}
/**
* 保证Shiro的声明周期
* @return
*/
@Bean
public LifecycleBeanPostProcessor lifecycleBeanPostProcessor(){
return new LifecycleBeanPostProcessor();
}
/**
* 开启Shiro授权生效
* @return
*/
@Bean
public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(){
return new AuthorizationAttributeSourceAdvisor();
}
}
三:自定义授权类
import cn.zyzpp.service.user.UserService;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import java.util.Set;
/**
* Create by yster@foxmail.com 2018/5/17/017 20:38
*/
public class CustomRealm extends AuthorizingRealm {
private String ClassName =this.getClass().getName();
@Autowired
@Lazy //必须懒加载,否则Ehcache缓存注解及事务管理注解无效
private UserService userService;
{
super.setName(ClassName);
}
/**
* 权限处理
* @param principals
* @return
*/
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
String username = (String) principals.getPrimaryPrincipal();
// 从数据库或者缓存中获得角色数据
Set<String> roles = userService.getRolesByUserName(username);
Set<String> permissions = userService.getPermissionsByRoles(roles);
//上面的service层方法需要自己写
SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
simpleAuthorizationInfo.setStringPermissions(permissions);
simpleAuthorizationInfo.setRoles(roles);
return simpleAuthorizationInfo;
}
/**
* 认证处理
* @param token
* @return
* @throws AuthenticationException
*/
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
// 1.从主体传过来的认证信息中,获得用户名
String username = (String) token.getPrincipal();
// 2.通过用户名到数据库中获取凭证
String password = userService.getPasswordByUsername(username);
if(password == null) {
return null;
}
SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(username, password, ClassName);
return simpleAuthenticationInfo;
}
}
四:使用
1)登录验证:
@RequestMapping(value = "/login/result", method = RequestMethod.POST)
public String userLogin(User user) {
String error = null;
Subject subject = SecurityUtils.getSubject();
UsernamePasswordToken token = new UsernamePasswordToken(user.getMail(), user.getPassword());
try {
token.setRememberMe(user.isRememberMe());//记住我
subject.login(token);
} catch (UnknownAccountException e) {
error = "用户名/密码错误";
} catch (IncorrectCredentialsException e) {
error = "用户名/密码错误";
} catch (AuthenticationException e) {
//其他错误,比如锁定,如果想单独处理请单独catch处理
error = "其他错误:" + e.getMessage();
}
if(error != null) {//出错了,返回登录页面
} else {//登录成功
}
}
2)权限验证:
可以在配置文件中配置Url权限等,参考步骤二。
使用诸如 @RequiresRoles(“user”) 注解在controller层的方法上,进行角色验证,或者使用@RequiresPermissions(“index:hello”)进行权限验证,不过使用注解Shiro就只抛出异常,无法使用shiro设置自动跳转到页面等。针对这个问题,可以用@ControllerAdvice统一异常处理。
@RequiresRoles("user")
@RequestMapping(value = "/up")
public String up(){
}
本实例旨在讲解SpringBoot集成,Shiro教程推荐:http://wiki.jikexueyuan.com/project/shiro/
SpringBoot集成Shiro安全框架的更多相关文章
- SpringBoot学习笔记(五):SpringBoot集成lombok工具、SpringBoot集成Shiro安全框架
SpringBoot集成lombok工具 什么是lombok? 自动生成setget方法,构造函数,打印日志 官网:http://projectlombok.org/features/index. 平 ...
- 在前后端分离的SpringBoot项目中集成Shiro权限框架
参考[1].在前后端分离的SpringBoot项目中集成Shiro权限框架 参考[2]. Springboot + Vue + shiro 实现前后端分离.权限控制 以及跨域的问题也有涉及
- SpringBoot集成Shiro并用MongoDB做Session存储
之前项目鉴权一直使用的Shiro,那是在Spring MVC里面使用的比较多,而且都是用XML来配置,用Shiro来做权限控制相对比较简单而且成熟,而且我一直都把Shiro的session放在mong ...
- springboot集成shiro实现权限认证
github:https://github.com/peterowang/shiro 基于上一篇:springboot集成shiro实现身份认证 1.加入UserController package ...
- Springboot整合Shiro安全框架
最近在学习Springboot,在这个过程中遇到了很多之前都没有技术知识,学习了一阵子,稍微总结一些. ---- Shiro框架 shiro框架,是一个相对比较简便的安全框架,它可以干净利落地处理身份 ...
- SpringBoot集成Shiro 实现动态加载权限
一.前言 本文小编将基于 SpringBoot 集成 Shiro 实现动态uri权限,由前端vue在页面配置uri,Java后端动态刷新权限,不用重启项目,以及在页面分配给用户 角色 . 按钮 .ur ...
- springboot集成shiro 实现权限控制(转)
shiro apache shiro 是一个轻量级的身份验证与授权框架,与spring security 相比较,简单易用,灵活性高,springboot本身是提供了对security的支持,毕竟是自 ...
- SpringBoot集成Shiro实现权限控制
Shiro简介 Apache Shiro是一个功能强大且易于使用的Java安全框架,用于执行身份验证,授权,加密和会话管理.使用Shiro易于理解的API,您可以快速轻松地保护任何应用程序-从最小的移 ...
- 【Shiro】SpringBoot集成Shiro
项目版本: springboot2.x shiro:1.3.2 Maven配置: <dependency> <groupId>org.apache.shiro</grou ...
随机推荐
- leetcode-217存在重复元素
leetcode-217存在重复元素 题意 给定一个整数数组,判断是否存在重复元素. 如果任何值在数组中出现至少两次,函数返回 true.如果数组中每个元素都不相同,则返回 false. 示例 1: ...
- Android 内存管理中的 Shallow heap Retained heap
所有包含Heap Profling功能的工具(MAT,Yourkit,JProfiler,TPTP等)都会使用到两个名词,一个是Shallow heap Size,另一个是 Retained heap ...
- LeetCode题解之Binary Tree Right Side View
1.题目描述 2.问题分析 使用层序遍历 3.代码 vector<int> v; vector<int> rightSideView(TreeNode* root) { if ...
- windows网络编程中文 笔记(二)
IPv4 地址段 IPv4地址类别 种类 网络部分 第1个数字 端点数字 A 8位 0-127 16777216 B 16位 128-191 65526 C 24位 193-223 ...
- C#-方法(八)
方法是什么 方法是C#中将一堆代码进行进行重用的机制 他是在类中实现一种特定功能的代码块,将重复性功能提取出来定义一个新的方法 这样可以提高代码的复用性,使编写程序更加快捷迅速 方法格式 访问修饰符 ...
- SQL2008无法附加数据库,提示“无法显示请求的对话框”(nColIndex实际值是-1)图文解决方法
SQL2008无法附加数据库,提示“无法显示请求的对话框”(nColIndex实际值是-1)图文解决方法 SQL2008无法附加数据库,提示“无法显示请求的对话框”(nColIndex实际值是-1)图 ...
- java学习(权限修饰符)
Java中,可以使用访问控制符来保护对类.变量.方法和构造方法的访问.Java 支持 4 种不同的访问权限. default (即缺省,什么也不写): 在同一包内可见,不使用任何修饰符.使用对象:类. ...
- JavaScript -- 时光流逝(十):Screen 对象、History 对象、Location 对象
JavaScript -- 知识点回顾篇(十):Screen 对象.History 对象.Location 对象 1. Screen 对象 1.1 Screen 对象的属性 (1) availHeig ...
- June 8. 2018 Week Week 23rd Friday
You'll have bad times, but it'll always wake you up to the good stuff you weren't paying attention t ...
- Linux常用命令-文本查看篇
前言 Linux常用命令中,除了cat还有很多其他用于文本查看的命令.本文将简单介绍一下这些文本查看的命令. 全文本显示--cat cat可能是常用的一个文本查看命令了,使用方法也很简单: cat f ...