中国领先的工业平台

返回贤集网 返回微头条
贤集网技术微头条APP获取

SpringBoot集成Shiro进行权限控制和管理的示例

 山东大明消毒科技有限公司

下载贤集网APP入驻自媒体

shiro

apache shiro 是一个轻量级的身份验证与授权框架,与spring security 相比较,简单易用,灵活性高,springboot本身是提供了对security的支持,毕竟是自家的东西。springboot暂时没有集成shiro,这得自己配。

1 . 添加依赖

<dependency>

<groupId>org.apache.shiro</groupId>

<artifactId>shiro-spring</artifactId>

<version>1.2.5</version>

</dependency>

<dependency>

<groupId>org.apache.shiro</groupId>

<artifactId>shiro-ehcache</artifactId>

<version>1.2.5</version>

</dependency>

复制代码

2 . 编写Shiro配置类

package com.xbz.web.system.config;

import at.pollux.thymeleaf.shiro.dialect.ShiroDialect;

import org.apache.shiro.authc.credential.CredentialsMatcher;

import org.apache.shiro.authc.credential.HashedCredentialsMatcher;

import org.apache.shiro.cache.ehcache.EhCacheManager;

import org.apache.shiro.codec.Base64;

import org.apache.shiro.session.SessionListener;

import org.apache.shiro.session.mgt.SessionManager;

import org.apache.shiro.session.mgt.eis.MemorySessionDAO;

import org.apache.shiro.session.mgt.eis.SessionDAO;

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.apache.shiro.web.session.mgt.DefaultWebSessionManager;

import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;

import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;

import org.springframework.context.annotation.Bean;

import org.springframework.context.annotation.Configuration;

import org.springframework.context.annotation.DependsOn;

import java.util.ArrayList;

import java.util.Collection;

import java.util.LinkedHashMap;

import java.util.Map;

/**

* shiro配置类

* ApacheShiro核心通过Filter来实现权限控制和拦截 , 就好像SpringMVC通过DispachServlet来主控制请求分发一样 .

* 既然是使用Filter , 即是通过URL规则来进行过滤和权限校验 , 所以我们需要定义一系列关于URL的规则和访问权限

*/

@Configuration

public class ShiroConfiguration {

/**

* DefaultAdvisorAutoProxyCreator , Spring的一个bean , 由Advisor决定对哪些类的方法进行AOP代理 .

*/

[url=home.php?mod=space&uid=4377]@Bean[/url]

@ConditionalOnMissingBean


}

复制代码

3 . 自定义Realm验证类

package com.yiyun.web.system.config;

import com.yiyun.dao.master.UserDao;

import com.yiyun.domain.UserDO;

import com.yiyun.web.common.utils.ShiroUtils;

import com.yiyun.web.system.service.MenuService;

import org.apache.shiro.SecurityUtils;

import org.apache.shiro.authc.*;

import org.apache.shiro.authz.AuthorizationInfo;

import org.apache.shiro.authz.SimpleAuthorizationInfo;

import org.apache.shiro.realm.AuthorizingRealm;

import org.apache.shiro.session.Session;

import org.apache.shiro.subject.PrincipalCollection;

import org.springframework.beans.factory.annotation.Autowired;

import java.util.*;

/**

* 获取用户的角色和权限信息

*/

public class ShiroRealm extends AuthorizingRealm {

// 一般这里都写的是servic

@Autowired

private UserDao userMapper;

@Autowired

private MenuService menuService;

/**

* 登录认证 一般情况下 , 登录成功之后就给当前用户进行权限赋予了

* 根据用户的权限信息做授权判断,这一步是以doGetAuthenticationInfo为基础的,只有在有用户信息后才能根据用户的角色和授权信息做判断是否给用户授权,因此这里的Roles和Permissions是用户的两个重点判断依据

* @param authenticationToken

* @return

* @throws AuthenticationException

*/

@Override

protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {

UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken;

UserDo user = userMapper.findByName(token.getUsername());//查出是否有此用户

if(user != null){

// 若存在,将此用户存放到登录认证info中,无需自己做密码对比,Shiro会为我们进行密码对比校验

List<URole> rlist = uRoleDao.findRoleByUid(user.getId());//获取用户角色

List<UPermission> plist = uPermissionDao.findPermissionByUid(user.getId());//获取用户权限

List<String> roleStrlist=new ArrayList<String>();////用户的角色集合

List<String> perminsStrlist=new ArrayList<String>();//用户的权限集合

for (URole role : rlist) {

roleStrlist.add(role.getName());

}

for (UPermission uPermission : plist) {

perminsStrlist.add(uPermission.getName());

}

user.setRoleStrlist(roleStrlist);

user.setPerminsStrlist(perminsStrlist);

Session session = SecurityUtils.getSubject().getSession();

session.setAttribute("user", user);//成功则放入session

// 若存在,将此用户存放到登录认证info中,无需自己做密码对比,Shiro会为我们进行密码对比校验

return new SimpleAuthenticationInfo(user, user.getPassword(), getName());

}

return null;

}

/**

* 权限认证

* 获取用户的权限信息,这是为下一步的授权做判断,获取当前用户的角色和这些角色所拥有的权限信息

* @param principalCollection

* @return

*/

@Override

protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {

//获取当前登录输入的用户名,等价于(String) principalCollection.fromRealm(getName()).iterator().next();

// String loginName = (String) super.getAvailablePrincipal(principalCollection);

UserDo user = (UserDo) principalCollection.getPrimaryPrincipal();

// //到数据库查是否有此对象

// User user = null;// 实际项目中,这里可以根据实际情况做缓存,如果不做,Shiro自己也是有时间间隔机制,2分钟内不会重复执行该方法

// user = userMapper.findByName(loginName);

if (user != null) {

//权限信息对象info,用来存放查出的用户的所有的角色(role)及权限(permission)

SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();

//用户的角色集合

info.addRoles(user.getRoleStrlist());

//用户的权限集合

info.addStringPermissions(user.getPerminsStrlist());

return info;

}

// 返回null的话,就会导致任何用户访问被拦截的请求时,都会自动跳转到unauthorizedUrl指定的地址

return null;

}

}

复制代码

4 . 最后看一下ehcache的配置文件

<?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/Tmp_EhCache" />

<!--

name:缓存名称。

maxElementsInMemory:缓存最大数目

maxElementsOnDisk:硬盘最大缓存个数。

eternal:对象是否永久有效,一但设置了,timeout将不起作用。

overflowToDisk:是否保存到磁盘,当系统当机时

timeToIdleSeconds:设置对象在失效前的允许闲置时间(单位:秒)。仅当eternal=false对象不是永久有效时使用,可选属性,默认值是0,也就是可闲置时间无穷大。

timeToLiveSeconds:设置对象在失效前允许存活时间(单位:秒)。最大时间介于创建时间和失效时间之间。仅当eternal=false对象不是永久有效时使用,默认是0.,也就是对象存活时间无穷大。

diskPersistent:是否缓存虚拟机重启期数据 Whether the disk store persists between restarts of the Virtual Machine. The default value is false.

diskSpoolBufferSizeMB:这个参数设置DiskStore(磁盘缓存)的缓存区大小。默认是30MB。每个Cache都应该有自己的一个缓冲区。

diskExpiryThreadIntervalSeconds:磁盘失效线程运行时间间隔,默认是120秒。

memoryStoreEvictionPolicy:当达到maxElementsInMemory限制时,Ehcache将会根据指定的策略去清理内存。默认策略是LRU(最近最少使用)。你可以设置为FIFO(先进先出)或是LFU(较少使用)。

clearOnFlush:内存数量最大时是否清除。

memoryStoreEvictionPolicy:

Ehcache的三种清空策略;

FIFO,first in first out,这个是大家最熟的,先进先出。

LFU, Less Frequently Used,就是上面例子中使用的策略,直白一点就是讲一直以来最少被使用的。如上面所讲,缓存的元素有一个hit属性,hit值最小的将会被清出缓存。

LRU,Least Recently Used,最近最少使用的,缓存的元素有一个时间戳,当缓存容量满了,而又需要腾出地方来缓存新的元素的时候,那么现有缓存元素中时间戳离当前时间最远的元素将被清出缓存。

-->

<defaultCache eternal="false" maxElementsInMemory="1000"

overflowToDisk="false" diskPersistent="false" timeToIdleSeconds="0"

timeToLiveSeconds="600" memoryStoreEvictionPolicy="LRU" />

<!-- 登录记录缓存锁定10分钟 -->

<cache name="passwordRetryCache"

maxEntriesLocalHeap="2000"

eternal="false"

timeToIdleSeconds="3600"

timeToLiveSeconds="0"

overflowToDisk="false"

statistics="true">

</cache>

</ehcache>

复制代码

以上就是本文的全部内容,希望对大家的学习有所帮助


最新回复

还没有人回复哦,抢沙发吧~

发布回复

为您推荐

热门交流