Shiro在SpringBoot中的使用
Demo代码请参考:https://github.com/roostinghawk/ShiroDemo
以下为主要代码(经过验证,测试)
1. pom.xml:引用shiro
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>${shiro.version}</version>
</dependency>
2. ShiroConfig(自定义config)
import liuwei.demo.shiro.consts.Const;
import liuwei.demo.shiro.realm.MyRealm;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.cache.ehcache.EhCacheManager;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.session.mgt.eis.EnterpriseCacheSessionDAO;
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.Cookie;
import org.apache.shiro.web.servlet.SimpleCookie;
import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.DependsOn; import javax.servlet.Filter;
import java.util.LinkedHashMap;
import java.util.Map; @Configuration
public class ShiroConfig { /**
* 全局
*/
@Bean
public ShiroFilterFactoryBean shiroFilter(SecurityManager securityManager){
ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
//设置安全管理器
shiroFilterFactoryBean.setSecurityManager(securityManager);
//默认跳转到登陆页面
shiroFilterFactoryBean.setLoginUrl("/login");
//登陆成功后的页面
shiroFilterFactoryBean.setSuccessUrl("/index");
shiroFilterFactoryBean.setUnauthorizedUrl("/403"); //自定义过滤器
Map<String,Filter> filterMap=new LinkedHashMap<>();
shiroFilterFactoryBean.setFilters(filterMap);
//权限控制map
Map<String,String> filterChainDefinitionMap=new LinkedHashMap<>();
// 配置不会被拦截的链接 顺序判断
filterChainDefinitionMap.put("/static/**", "anon");
filterChainDefinitionMap.put("/403", "anon");
//配置退出 过滤器,其中的具体的退出代码Shiro已经替我们实现了
filterChainDefinitionMap.put("/logout", "logout");
//<!-- 过滤链定义,从上向下顺序执行,一般将/**放在最为下边 -->
//<!-- authc:所有url都必须认证通过才可以访问; anon:所有url都都可以匿名访问-->
filterChainDefinitionMap.put("/**", "authc"); shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
return shiroFilterFactoryBean;
} /**
* 核心:SecurityManager
*/
@Bean
public SecurityManager securityManager(DefaultWebSessionManager sessionManager){
DefaultWebSecurityManager securityManager=new DefaultWebSecurityManager ();
//设置realm
securityManager.setRealm( myRealm() );
securityManager.setRememberMeManager(rememberMeManager());
securityManager.setCacheManager( ehCacheManager() );
securityManager.setSessionManager(sessionManager);
return securityManager;
} /**
* 身份认证Realm
*/
@Bean
public MyRealm myRealm(){
MyRealm myRealm = new MyRealm();
myRealm.setCredentialsMatcher( hashedCredentialsMatcher() );
return myRealm;
} /**
* 哈希密码比较器。在myShiroRealm中作用参数使用
* 登陆时会比较用户输入的密码,跟数据库密码配合盐值salt解密后是否一致。
* @return
*/
@Bean
public HashedCredentialsMatcher hashedCredentialsMatcher(){
HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher();
hashedCredentialsMatcher.setHashAlgorithmName(Const.HASH_ALGORITHM);
//散列的次数,比如散列两次,相当于 md5( md5(""));
hashedCredentialsMatcher.setHashIterations(Const.HASH_INTERATIONS);
return hashedCredentialsMatcher;
} @Bean(name = "sessionDao")
public EnterpriseCacheSessionDAO sessionDao(){
EnterpriseCacheSessionDAO sessionDao = new EnterpriseCacheSessionDAO();
sessionDao.setActiveSessionsCacheName("shiro-activeSessionCache");
return sessionDao;
} /**
* Session管理Bean
*/
@Bean(name = "sessionManager")
public DefaultWebSessionManager sessionManager(EnterpriseCacheSessionDAO sessionDAO) {
DefaultWebSessionManager sessionManager = new DefaultWebSessionManager();
sessionManager.setSessionDAO(sessionDAO);
sessionManager.setGlobalSessionTimeout(86400000);
sessionManager.setDeleteInvalidSessions(true);
sessionManager.setSessionValidationInterval(1800000);
sessionManager.setSessionValidationSchedulerEnabled(true);
Cookie cookie = new SimpleCookie("ad.es.session.id");
cookie.setHttpOnly(Boolean.FALSE);
cookie.setPath("/");
sessionManager.setSessionIdCookie(cookie);
sessionManager.setSessionIdCookieEnabled(true);
return sessionManager;
} /**
* 缓存:使用Ehcache
* @return
*/
@Bean
public EhCacheManager ehCacheManager(){
EhCacheManager cacheManager=new EhCacheManager();
cacheManager.setCacheManagerConfigFile("classpath:ehcache.xml");
return cacheManager;
} /**
* RememberMe
* @return
*/
@Bean
public CookieRememberMeManager rememberMeManager() {
CookieRememberMeManager cookieRememberMeManager = new CookieRememberMeManager();
cookieRememberMeManager.setCookie(rememberMeCookie());
//rememberMe cookie加密的密钥 默认AES算法
// cookieRememberMeManager.setCipherKey();
return cookieRememberMeManager;
} /**
* cookie对象
* @return
*/
@Bean
public Cookie rememberMeCookie() {
SimpleCookie simpleCookie=new SimpleCookie("rememberMe");
//记住我cookie生效时间,单位秒
simpleCookie.setMaxAge(3600);
return simpleCookie;
} /**
* 开启shiro aop注解支持.
* 使用代理方式;所以需要开启代码支持;否则@RequiresRoles等注解无法生效
* @param securityManager
* @return
*/
@Bean
public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager){
AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);
return authorizationAttributeSourceAdvisor;
} /**
* Shiro生命周期处理器
* @return
*/
@Bean
public LifecycleBeanPostProcessor lifecycleBeanPostProcessor(){
return new LifecycleBeanPostProcessor();
} /**
* 自动创建代理
* @return
*/
@Bean
@DependsOn({"lifecycleBeanPostProcessor"})
public DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator(){
DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator = new DefaultAdvisorAutoProxyCreator();
advisorAutoProxyCreator.setProxyTargetClass(true);
return advisorAutoProxyCreator;
}
}
3. MyRealm(自定义Realm)
import liuwei.demo.shiro.model.Permission;
import liuwei.demo.shiro.model.Role;
import liuwei.demo.shiro.model.User;
import liuwei.demo.shiro.service.UserService;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.codec.Hex;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource; import javax.annotation.Resource;
import java.util.HashSet;
import java.util.List;
import java.util.Set; public class MyRealm extends AuthorizingRealm { @Resource(name = "userServiceImpl")
private UserService userService; /**
* 提供帐户信息,返回认证信息
* @param authenticationToken
* @return
* @throws AuthenticationException
*/
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
String loginName = (String)authenticationToken.getPrincipal();
User user = userService.findUserByLoginName(loginName);
if(user == null) {
//用户不存在就抛出异常
throw new UnknownAccountException();
} //密码可以通过SimpleHash加密,然后保存进数据库。
//此处是获取数据库内的账号、密码、盐值,保存到登陆信息info中
return new SimpleAuthenticationInfo(
loginName,
user.getPassword(),
ByteSource.Util.bytes(Hex.decode(user.getSalt())),
getName());
} /**
* 提供用户信息,返回权限信息
* @param principals
* @return
*/
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
String loginName = (String) principals.getPrimaryPrincipal();
User user = userService.findUserByLoginName(loginName);
List<Role> roles = userService.findRolesByUid(Integer.parseInt(user.getUid()));
Set<String> roleSet = new HashSet<>();
Set<String> permissionSet = new HashSet<>();
for(Role role : roles) {
roleSet.add(role.getRole());
List<Permission> permissions = userService.findPermissionsByRoleId(role.getId());
for(Permission permission : permissions) {
permissionSet.add(permission.getPermission());
}
}
// 将角色名称提供给授权info
authorizationInfo.setRoles(roleSet);
// 将权限名称提供给info
authorizationInfo.setStringPermissions(permissionSet); return authorizationInfo;
}
}
4. ehcache.xml:缓存配置(可不用)
<?xml version="1.0" encoding="UTF-8"?>
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd"
updateCheck="false">
<diskStore path="java.io.tmpdir/demo_EhCache" /> <!--
defaultCache:默认缓存策略,当ehcache找不到定义的缓存时,则使用这个缓存策略。只能定义一个。
--> <defaultCache
eternal="false"
maxElementsInMemory="1000"
overflowToDisk="false"
diskPersistent="false"
timeToIdleSeconds="0"
timeToLiveSeconds="600"
memoryStoreEvictionPolicy="LRU" /> <cache name="users"
maxEntriesLocalHeap="200"
timeToLiveSeconds="600">
</cache>
</ehcache>
很简单,如遇到问题,请在评论回复!
Shiro在SpringBoot中的使用的更多相关文章
- [Shiro] - Shiro之SpringBoot中的使用
下载了运行项目后,访问路径:http://localhost/shiro/login 这篇应该在进阶后面的. shiro中的重中之重,一定要看. 基于springboot+thymeleaf+shir ...
- SpringBoot中Shiro缓存使用Redis、Ehcache
在SpringBoot中Shiro缓存使用Redis.Ehcache实现的两种方式实例 SpringBoot 中配置redis作为session 缓存器. 让shiro引用 本文是建立在你是使用这sh ...
- SpringBoot中Shiro使用Pac4j集成CAS认证
SpringBoot中Shiro使用Pac4j集成CAS认证 Pac4j 简介 Pac4j与Shiro,Spring Security一样都是权限框架,并且提供了OAuth - SAML - CAS ...
- SpringBoot中整合Redis、Ehcache使用配置切换 并且整合到Shiro中
在SpringBoot中Shiro缓存使用Redis.Ehcache实现的两种方式实例 SpringBoot 中配置redis作为session 缓存器. 让shiro引用 本文是建立在你是使用这sh ...
- 记录一下在SpringBoot中实现简单的登录认证
代码参考博客: https://blog.csdn.net/weixin_37891479/article/details/79527641 在做学校的课设的时候,发现了安全的问题,就不怀好意的用户有 ...
- SpringBoot中application.yml基本配置详情
把原有的application.properties删掉.然后 maven -X clean install,或者通过Maven Project双击clean和install(1)端口服务配置 #端口 ...
- 【Shiro】SpringBoot集成Shiro
项目版本: springboot2.x shiro:1.3.2 Maven配置: <dependency> <groupId>org.apache.shiro</grou ...
- Shiro (Shiro + JWT + SpringBoot应用)
Shiro (Shiro + JWT + SpringBoot应用) 目录 Shiro (Shiro + JWT + SpringBoot应用) 1.Shiro的简介 2.Shiro + JWT + ...
- SpringBoot中yaml配置对象
转载请在页首注明作者与出处 一:前言 YAML可以代替传统的xx.properties文件,但是它支持声明map,数组,list,字符串,boolean值,数值,NULL,日期,基本满足开发过程中的所 ...
随机推荐
- 第08章 ElasticSearch Java API
本章内容 使用客户端对象(client object)连接到本地或远程ElasticSearch集群. 逐条或批量索引文档. 更新文档内容. 使用各种ElasticSearch支持的查询方式. 处理E ...
- .NET基础 (04)基础类型和语法
基础类型和语法1 .NET中所有内建类型的基类是什么2 System.Object中包含哪些方法,哪些是虚方法3 值类型和引用类型的区别4 简述装箱和拆箱原理5 C#中是否有全局变量6 struct和 ...
- 一、Numpy基础--数组
(一)Numpy数组对象 Numpy中的nadrray是一个多维数组对象,该对象由两部分组成: 实际的数据 描述这些数据的元数据 大部分的数组操作仅仅修改元数据部分,而不改变底层的实际数据. 数组的数 ...
- Intel GPA果然是神器
又一次PERF暗黑三...只有GPA帮到了我. Intel GPA是一个用于测试产品性能和质量的工具.使用这个工具可以运行在游戏或3D应用程序中用来看看它们是如何工作的,其优势性的一点是,有了Auto ...
- Linq扩展最后遗留之SelectMany,Zip,SequenceEqual源码分析
Linq扩展最后遗留之SelectMany,Zip,SequenceEqual源码分析 一: AsParallel [并行化查询] 这个函数的功效就是将计算结果多线程化.[并行计算] =>[多核 ...
- Windows store app[Part 1]:读取U盘数据
Windows 8系统下开发App程序,对于.NET程序员来说,需要重新熟悉下类库. 关于WinRT,引用一张网上传的很多的结构图: 图1 针对App的开发,App工作在系统划定的安全沙箱内,所以通过 ...
- Spring MVC 基本配制
WEB.XML 文件中的配制: <?xml version="1.0" encoding="UTF-8"?> <web-app id=&quo ...
- asp.net mvc+webuploader大文件分片上传
首先是前端: var GUID = WebUploader.Base.guid();//一个GUID uploadereditsVideo = WebUploader.create({ // swf文 ...
- C++三种野指针及应对/内存泄露
C++三种野指针及应对/内存泄露 野指针,也就是指向不可用内存区域的指针.如果对野指针进行操作,将会使程序发生不可预知的错误,甚至可能直接引起崩溃. 野指针不是NULL指针,是指 ...
- 理解ASP.NET MVC引擎处理模型字符串的默认行为,涉及Html.Raw()和HttpUtility.HtmlDecode()
MVC引擎默认会将Model属性值中包含的html字符串做encode,所以如属性中包含类似 <br> 这样的标记,MVC引擎会将它们转换成html实体码 %3Cbr%3E 所以1:在编辑 ...