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中的使用的更多相关文章

  1. [Shiro] - Shiro之SpringBoot中的使用

    下载了运行项目后,访问路径:http://localhost/shiro/login 这篇应该在进阶后面的. shiro中的重中之重,一定要看. 基于springboot+thymeleaf+shir ...

  2. SpringBoot中Shiro缓存使用Redis、Ehcache

    在SpringBoot中Shiro缓存使用Redis.Ehcache实现的两种方式实例 SpringBoot 中配置redis作为session 缓存器. 让shiro引用 本文是建立在你是使用这sh ...

  3. SpringBoot中Shiro使用Pac4j集成CAS认证

    SpringBoot中Shiro使用Pac4j集成CAS认证 Pac4j 简介 Pac4j与Shiro,Spring Security一样都是权限框架,并且提供了OAuth - SAML - CAS ...

  4. SpringBoot中整合Redis、Ehcache使用配置切换 并且整合到Shiro中

    在SpringBoot中Shiro缓存使用Redis.Ehcache实现的两种方式实例 SpringBoot 中配置redis作为session 缓存器. 让shiro引用 本文是建立在你是使用这sh ...

  5. 记录一下在SpringBoot中实现简单的登录认证

    代码参考博客: https://blog.csdn.net/weixin_37891479/article/details/79527641 在做学校的课设的时候,发现了安全的问题,就不怀好意的用户有 ...

  6. SpringBoot中application.yml基本配置详情

    把原有的application.properties删掉.然后 maven -X clean install,或者通过Maven Project双击clean和install(1)端口服务配置 #端口 ...

  7. 【Shiro】SpringBoot集成Shiro

    项目版本: springboot2.x shiro:1.3.2 Maven配置: <dependency> <groupId>org.apache.shiro</grou ...

  8. Shiro (Shiro + JWT + SpringBoot应用)

    Shiro (Shiro + JWT + SpringBoot应用) 目录 Shiro (Shiro + JWT + SpringBoot应用) 1.Shiro的简介 2.Shiro + JWT + ...

  9. SpringBoot中yaml配置对象

    转载请在页首注明作者与出处 一:前言 YAML可以代替传统的xx.properties文件,但是它支持声明map,数组,list,字符串,boolean值,数值,NULL,日期,基本满足开发过程中的所 ...

随机推荐

  1. mysql中查看表结构的sql语句

    mysql查看表结构命令,如下: desc 表名;show columns from 表名;describe 表名;show create table 表名; use information_sche ...

  2. 手把手教你看KEGG通路图!

    手把手教你看KEGG通路图! 亲爱的小伙伴们,是不是正关注代谢通路研究?或者你正面对数据,绞尽脑汁?小编当然不能让亲们这么辛苦,今天就跟大家分享KEGG代谢通路图的正确解读方法,还在迷糊中的小伙伴赶紧 ...

  3. java调.NET webapi时间戳报错问题

    JAVA时间戳长度是13位,如:1294890876859 PHP .NET时间戳长度是10位, 如:1294890859 主要最后三位的不同,JAVA时间戳在.NETPHP中使用,去掉后三位,如:1 ...

  4. HDU 1159 Common Subsequence (LCS)

    题意:给定两行字符串,求最长公共子序列. 析:dp[i][j] 表示第一串以 i 个结尾和第二个串以 j 个结尾,最长公共子序列,剩下的就简单了. 代码如下: #pragma comment(link ...

  5. 编写高质量代码改善C#程序的157个建议——建议139:事件处理器命名采用组合方式

    建议139:事件处理器命名采用组合方式 所谓事件处理器,就是实际被委托执行的那个方法.查看如下代码: public MainWindow() { InitializeComponent(); Butt ...

  6. 《T-SQL查询》- SQL逻辑处理

    下面列出SQL查询语句的一般形式,以及各个子句被逻辑处理的顺序步骤: (8) SELECT (9) DISTINCT (11) <TOP_specification> <select ...

  7. mybatis-初步使用

    最近因为业务各方面的原因,需要使用mybatis,所以系统的学习和总结下. 其实mybatis出来已经很久了,貌似大家伙用得也挺顺手的样纸,好歹我先不评价,还是先了解了解mybatis的样纸,后续再添 ...

  8. Transaction And Lock--解决死锁/锁的几种有效方式

    修改资源访问顺序,使多个事务对资源的访问方式一致优化查询SELECT,使得S锁能尽早释放均可能将更新和删除语句放到事务末端(使得X锁占用时间最小)避免事务执行期间暂停或等待外部输入将较大事务拆分成多个 ...

  9. 【项目总结】扯一扯电商网站前端css的整体架构设计(1)

    最近半忙不忙的写了一个外包网站,网站主要功能是艺术品竞拍和艺术衍生品的销售.工程已经完成了80%左右,现在前后端代码量已经50W行左右,我主要负责的是前端设计和前端布局.下面就先放一个网站的设计图吧, ...

  10. google chrome 调试技巧:监控 DOM 元素被修改

    在很多时候, 页面上一个元素的属于被修改.删除,子节点的添加与修改,很难一下找到对应的代码,在 google chrome 开发者工具里, 提供了对 DOM 元素的监控: 在 Elements 标签, ...