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. tree.J48

    Weka为一个Java基础上的机器学习工具.上手简单,并提供图形化界面.提供如分类.聚类.频繁项挖掘等工具.本篇文章主要写一下分类器算法中的J48算法及事实上现. 一.算法 J48是基于C4.5实现的 ...

  2. 重定向和请求转发后面加“return;”语句

    请求转发  RequestDispatcher 重定向     Redirect 代码的执行: 无论是 request.getRequestDispatcher(path).forward(reque ...

  3. tomcat端口作用

    <Server port="8005" shutdown="SHUTDOWN">   <Connector port="8080&q ...

  4. Perl语言编程>>学习笔记

    1. 使用反引号可以调用外部程序并返回程序的输出, 如  $cwd = `pwd`; 2. Perl 中的变量类型之间的区别主要是单数和复数; 单数变量称为标量 $scalar , 复数变量称为数组 ...

  5. 删除 Ceph 的image报rbd: error: image still has watchers

    在Ceph集群日常运维中,管理员可能会遇到有的image删除不了的情况,有一种情况是由于image下有快照信息,只需要先将快照信息清除,然后再删除该image即可,还有一种情况是因为该image仍旧被 ...

  6. Spring MVC @RequestMapping浅析

    简介:@RequestMappingRequestMapping是一个用来处理请求地址映射的注解,可用于类或方法上.用于类上,表示类中的所有响应请求的方法都是以该地址作为父路径.RequestMapp ...

  7. 编写高质量代码改善C#程序的157个建议——建议119:不要使用自己的加密算法

    建议119:不要使用自己的加密算法 很多人认为自己写的加密算法才是安全的,因为该算法只有“自己知道”.很遗憾,这是大错特错. 首先,我们不是秘密学专家,如果我们随随便便写个算法就称得上是加密算法的话, ...

  8. 编写高质量代码改善C#程序的157个建议——建议96:成员应优先考虑公开基类型或接口

    建议96:成员应优先考虑公开基类型或接口 类型成员如果优先考虑公开及类型或接口,那么会让类型支持更多的应用场合. FCL中最典型的例子是集合的功能操作.集合根据功能划分有多种类型,比如List< ...

  9. [Selenium With C#基础教程] Lesson-05 文本框

    作者:Surpassme 来源:http://www.jianshu.com/p/7dca7d0d1ea3 声明:本文为原创文章,如需转载请在文章页面明显位置给出原文链接,谢谢. 文本框在Web页面中 ...

  10. 【小梅哥SOPC学习笔记】SOPC开发常见问题及解决办法集锦

    SOPC开发常见问题及解决办法集锦 一.Symbol 'NULL' could not be resolved 近期在评估使用NIOS II处理器进行项目的开发,我使用的软件是Quartus II 1 ...