SpringBoot配置shiro安全框架的实现
更新时间:2021年4月27日 20:01 点击:1745
首先引入pom
<!--SpringBoot 2.1.0--> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.1.0.RELEASE</version> </parent> <!--shiro--> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-core</artifactId> <version>${shiro.version}</version> </dependency> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-web</artifactId> <version>${shiro.version}</version> </dependency> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-spring</artifactId> <version>${shiro.version}</version> </dependency> <!-- shiro-redis --> <dependency> <groupId>org.crazycake</groupId> <artifactId>shiro-redis</artifactId> <version>3.1.0</version> </dependency> <!-- shiro-freemarker-tag --> <dependency> <groupId>net.mingsoft</groupId> <artifactId>shiro-freemarker-tags</artifactId> <version>1.0.0</version> </dependency> <!-- freemarker --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-freemarker</artifactId> </dependency>
ShiroConfig.java
package com.jx.cert.web.framework.config.shiro; import java.util.LinkedHashMap; import java.util.Map; import javax.servlet.Filter; import org.apache.shiro.authc.credential.HashedCredentialsMatcher; import org.apache.shiro.cache.MemoryConstrainedCacheManager; import org.apache.shiro.mgt.SecurityManager; import org.apache.shiro.session.mgt.SessionManager; import org.apache.shiro.spring.LifecycleBeanPostProcessor; import org.apache.shiro.spring.web.ShiroFilterFactoryBean; import org.apache.shiro.web.mgt.DefaultWebSecurityManager; import org.crazycake.shiro.RedisCacheManager; import org.crazycake.shiro.RedisManager; import org.crazycake.shiro.RedisSessionDAO; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.DependsOn; import com.jx.cert.web.framework.config.shiro.filter.KickoutSessionControlFilter; import com.jx.cert.web.framework.config.shiro.filter.ShiroPermissionsFilter; import com.jx.cert.web.framework.config.shiro.filter.SystemLogoutFilter; import com.jx.common.utils.CacheConstants; /** * @ClassName: gyu * @Description: TODO(shrio配置) * @author gangyu * @date 2018年12月4日 下午2:28:07 */ @Configuration public class ShiroConfig { Logger log=LoggerFactory.getLogger(ShiroConfig.class); @Value("${spring.redis.host}") private String host; @Value("${spring.redis.prot}") private int port; @Value("${spring.redis.timeout}") private int timeout; @Value("${spring.redis.password}") private String password; @Value("${spring.redis.database}") private int database; //注意这里需要设置成 static 否则 @Value 注入不了数据 @Bean(name = "lifecycleBeanPostProcessor") public static LifecycleBeanPostProcessor lifecycleBeanPostProcessor() { return new LifecycleBeanPostProcessor(); } @Bean(name = "shiroFilter") public ShiroFilterFactoryBean shirFilter(SecurityManager securityManager) { ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean(); log.debug("-----------------Shiro拦截器工厂类注入开始"); Map<String,Filter> filterMap=shiroFilterFactoryBean.getFilters(); //权限过滤器 filterMap.put("perms", new ShiroPermissionsFilter()); shiroFilterFactoryBean.setFilters(filterMap); // 配置shiro安全管理器 SecurityManager shiroFilterFactoryBean.setSecurityManager(securityManager); // 指定要求登录时的链接 shiroFilterFactoryBean.setLoginUrl("/login"); // 登录成功后要跳转的链接 shiroFilterFactoryBean.setSuccessUrl("/index"); // filterChainDefinitions拦截器=map必须用:LinkedHashMap,因为它必须保证有序 Map<String, String> filterChainDefinitionMap = new LinkedHashMap<String, String>(); //对外应用开发接口不验证 filterChainDefinitionMap.put("/app/**", "anon"); filterChainDefinitionMap.put("/ajaxLogin", "anon"); // 放开验证码 filterChainDefinitionMap.put("/public/getGifCode", "anon"); // 退出 filterChainDefinitionMap.put("/logout", "logout"); //TODO 全部放行 // filterChainDefinitionMap.put("/manage/**", "anon[*]"); //公共资源 filterChainDefinitionMap.put("/static/**", "anon"); filterChainDefinitionMap.put("/css/**", "anon"); filterChainDefinitionMap.put("/img/**", "anon"); filterChainDefinitionMap.put("/js/**", "anon"); // authc:所有url都必须认证通过才可以访问; filterChainDefinitionMap.put("/**", "authc"); shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap); log.debug("-----------------Shiro拦截器工厂类注入成功"); return shiroFilterFactoryBean; } @Bean public HashedCredentialsMatcher hashedCredentialsMatcher() { HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher(); hashedCredentialsMatcher.setHashAlgorithmName("MD5");//散列算法:这里使用MD5算法; hashedCredentialsMatcher.setHashIterations(1);//散列的次数,比如散列两次,相当于 md5(md5("")); return hashedCredentialsMatcher; } //权限缓存到内存 @Bean(name = "shiroRealm") @DependsOn("lifecycleBeanPostProcessor") public MyShiroRealm myShiroRealm() { MyShiroRealm myShiroRealm = new MyShiroRealm(); myShiroRealm.setCacheManager(new MemoryConstrainedCacheManager()); myShiroRealm.setCredentialsMatcher(hashedCredentialsMatcher()); return myShiroRealm; } @Bean(name = "securityManager") public SecurityManager securityManager() { DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager(); securityManager.setRealm(myShiroRealm()); // 自定义session管理 使用redis securityManager.setSessionManager(sessionManager()); // 自定义缓存实现 使用redis securityManager.setCacheManager(cacheManager()); return securityManager; } /** * 配置shiro redisManager * @return */ public RedisManager redisManager() { RedisManager redisManager = new RedisManager(); redisManager.setHost(host); redisManager.setPort(port); redisManager.setTimeout(timeout); // redisManager.setPassword(password); redisManager.setDatabase(database); return redisManager; } //自定义sessionManager @Bean public SessionManager sessionManager() { MySessionManager mySessionManager = new MySessionManager(); mySessionManager.setSessionDAO(redisSessionDAO()); //默认1个小时session过期 mySessionManager.setGlobalSessionTimeout(CacheConstants.SHIRO_SESSION_MS); return mySessionManager; } /** * RedisSessionDAO shiro sessionDao层的实现 通过redis */ @Bean public RedisSessionDAO redisSessionDAO() { RedisSessionDAO redisSessionDAO = new RedisSessionDAO(); redisSessionDAO.setRedisManager(redisManager()); return redisSessionDAO; } /** * cacheManager 缓存 redis实现 * @return */ @Bean public RedisCacheManager cacheManager() { RedisCacheManager redisCacheManager = new RedisCacheManager(); redisCacheManager.setRedisManager(redisManager()); redisCacheManager.setExpire(CacheConstants.USER_DATA_TTL); return redisCacheManager; } }
MyShiroRealm.java
package com.jx.cert.web.framework.config.shiro; import java.util.ArrayList; import java.util.List; import org.apache.commons.codec.digest.DigestUtils; import org.apache.shiro.authc.AuthenticationException; import org.apache.shiro.authc.AuthenticationInfo; import org.apache.shiro.authc.AuthenticationToken; import org.apache.shiro.authc.LockedAccountException; import org.apache.shiro.authc.SimpleAuthenticationInfo; import org.apache.shiro.authc.UnknownAccountException; 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.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import com.jx.cert.web.framework.config.shiro.exception.SysUsreNotLoginAPPException; import com.jx.cert.web.framework.config.shiro.exception.SystemNotExistException; import com.jx.common.utils.SysCode; import com.jx.core.api.model.vo.cert.SysPermission; import com.jx.core.api.model.vo.cert.SysRole; import com.jx.core.api.model.vo.cert.SysSystem; import com.jx.core.api.model.vo.cert.SysUser; import com.jx.core.api.service.business.cert.SysPermissionService; import com.jx.core.api.service.business.cert.SysRoleService; import com.jx.core.api.service.business.cert.SysSystemService; import com.jx.core.api.service.business.cert.SysUserService; public class MyShiroRealm extends AuthorizingRealm { private Logger logger = LoggerFactory.getLogger(MyShiroRealm.class); @Autowired private SysUserService sysUserService; @Autowired private SysRoleService sysRoleService; @Autowired private SysPermissionService sysPermissionService; @Autowired private SysSystemService systemService; @Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) { logger.info("####################开始配置权限####################"); SysUser user = (SysUser) principals.getPrimaryPrincipal(); if (user != null) { //权限信息对象info,用来存放查出的用户的所有的角色(role)及权限(permission) SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo(); List<String> roleStrlist = new ArrayList<String>();//用户的角色集合 List<String> perminsStrlist = new ArrayList<String>();//用户的菜单权限集合 for (SysRole role : user.getRoleList()) { roleStrlist.add(role.getRoleName()); } for (SysPermission permission : user.getPermissList()) { perminsStrlist.add(permission.getUrl()); } //用户的角色集合 authorizationInfo.addRoles(roleStrlist); //用户的菜单按钮权限集合 authorizationInfo.addStringPermissions(perminsStrlist); return authorizationInfo; } return null; } /*主要是用来进行身份认证的,也就是说验证用户输入的账号和密码是否正确。*/ @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException { logger.info("####################身份认证####################"); String userStr = (String) token.getPrincipal(); SysUser user = sysUserService.getUserByUserName(userName); //认证系统用户 List<SysRole> roleList = sysRoleService.findRoleByUserId(user.getUserId(),systemId); user.setRoleList(roleList);//获取用户角色 List<SysPermission> list=sysPermissionService.getUserPermission(user.getUserId(),systemId); SysPermission permis=new SysPermission(); list.add(permis); user.setPermissList(list);//获取用户权限 return new SimpleAuthenticationInfo(user, DigestUtils.md5Hex(user.getPassword()),getName()); } }
ShiroTagsFreeMarkerCfg.java
package com.jx.cert.web.framework.config.shiro; import javax.annotation.PostConstruct; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer; import com.jagregory.shiro.freemarker.ShiroTags; import freemarker.template.TemplateModelException; /** * @ClassName: ShiroTagsFreeMarkerCfg * @Description: TODO(ftl shiro 标签) * @author gangyu * @date 2018年12月5日 下午5:16:27 * */ @Component public class ShiroTagsFreeMarkerCfg { @Autowired private FreeMarkerConfigurer freeMarkerConfigurer; @PostConstruct public void setSharedVariable() throws TemplateModelException { freeMarkerConfigurer.getConfiguration().setSharedVariable("shiro", new ShiroTags()); } }
ShiroPermissionsFilter.java
/** * @Title: ShiroPermissionsFilter.java * @Package com.jx.cert.web.config.shiro * @Description: TODO(用一句话描述该文件做什么) * @author gangyu * @date 2018年12月5日 上午11:47:00 * @version V1.0 */ package com.jx.cert.web.framework.config.shiro.filter; import java.io.IOException; import java.io.PrintWriter; import java.util.List; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.shiro.web.filter.authz.PermissionsAuthorizationFilter; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.google.gson.Gson; import com.jx.cert.web.framework.config.shiro.ShiroUtil; import com.jx.common.utils.Result; import com.jx.common.utils.enums.CodeEnum; import com.jx.core.api.model.vo.cert.SysPermission; import com.jx.core.api.model.vo.cert.SysUser; /** * @ClassName: ShiroPermissionsFilter * @Description: TODO(权限验证) * @author gangyu * @date 2018年12月5日 上午11:47:00 */ public class ShiroPermissionsFilter extends PermissionsAuthorizationFilter { private static final Logger logger = LoggerFactory.getLogger(ShiroPermissionsFilter.class); /** * 权限检测验证 */ @Override protected boolean onAccessDenied(ServletRequest servletRequest, ServletResponse servletResponse) throws IOException { logger.info("----------权限校验-------------"); HttpServletRequest request = (HttpServletRequest) servletRequest; HttpServletResponse response = (HttpServletResponse) servletResponse; String reqUrl=request.getRequestURI(); List<SysPermission> permsList=ShiroUtil.getUser().getPermissList(); String contextPath=request.getContextPath(); reqUrl=reqUrl.substring(contextPath.length()+1, reqUrl.length()); String header = request.getHeader("X-Requested-With"); boolean isAjax = "XMLHttpRequest".equals(header); SysUser user=ShiroUtil.getUser(); if(!new Gson().toJson(permsList).contains(reqUrl)){ if (isAjax) { logger.info("----------AJAX请求拒绝-------------"); response.setCharacterEncoding("UTF-8"); response.setContentType("application/json"); response.getWriter().write(new Gson().toJson(new Result(CodeEnum.NOT_PERMISSION))); } else { logger.info("----------普通请求拒绝-------------"); response.sendRedirect(request.getContextPath()+"/403"); } return false; }else { return true; } } }
ShiroUtil.java
package com.jx.cert.web.framework.config.shiro; import org.apache.shiro.SecurityUtils; import org.apache.shiro.session.Session; import org.apache.shiro.subject.Subject; import com.jx.core.api.model.vo.cert.SysUser; public class ShiroUtil { /** * 获取当前 Subject * * @return */ public static Subject getSubject() { return SecurityUtils.getSubject(); } /** * 获取shiro指定的sessionKey * * @param key * @param <T> * @return */ public static <T> T getSessionAttr(String key) { Session session = getSession(); return session != null ? (T) session.getAttribute(key) : null; } /** * 设置shiro指定的sessionKey * * @param key * @param value */ public static void setSessionAttr(String key, Object value) { Session session = getSession(); session.setAttribute(key, value); } /** * 获取当前用户对象 * * @return */ public static SysUser getUser() { if(getSubject().isAuthenticated()){ return (SysUser) getSubject().getPrincipals().getPrimaryPrincipal(); } return null; } /** * 获取当前用户对象UserID * * @return */ public static String getUserId() { return getUser().getUserId(); } /** * 移除shiro指定的sessionKey * * @param key */ public static void removeSessionAttr(String key) { Session session = getSession(); if (session != null) session.removeAttribute(key); } /** * 验证当前用户是否属于该角色 * * @param roleName 角色名称 * @return 属于该角色:true,否则false */ public static boolean hasRole(String roleName) { return getSubject() != null && roleName != null && roleName.length() > 0 && getSubject().hasRole(roleName); } /** * shiro 中获取session * * @return session */ public static Session getSession() { return getSubject().getSession(); } /** * 验证当前用户是否属于以下所有角色 * 多权限“,”分割 * * @param roleNames 权限名称 * @return 属于:true,否则false */ public static boolean hasAllRoles(String roleNames) { boolean hasAllRole = true; Subject subject = getSubject(); if (subject != null && roleNames != null && roleNames.length() > 0) { for (String role : roleNames.split(",")) { if (!subject.hasRole(role.trim())) { hasAllRole = false; break; } } } return hasAllRole; } /** * 验证当前用户是否属于以下任意一个角色 * 多权限“,”分割 * @param roleNames * @return */ public static boolean hasAnyRoles(String roleNames) { boolean hasAnyRole = false; Subject subject = getSubject(); if (subject != null && roleNames != null && roleNames.length() > 0) { for (String role : roleNames.split(",")) { if (subject.hasRole(role.trim())) { hasAnyRole = true; break; } } } return hasAnyRole; } }
到此这篇关于SpringBoot配置shiro安全框架的实现的文章就介绍到这了,更多相关SpringBoot配置shiro内容请搜索猪先飞以前的文章或继续浏览下面的相关文章希望大家以后多多支持猪先飞!
上一篇: Java基础之颜色工具类(超详细注释)
相关文章
IntelliJ IDEA2021.1 配置大全(超详细教程)
这篇文章主要介绍了IntelliJ IDEA2021.1 配置大全(超详细教程),需要的朋友可以参考下...2021-04-18- VPN可以虚拟出一个专用网络,让远处的计算机和你相当于处在同一个局域网中,而中间的数据也可以实现加密传输,用处很大,特别是在一些大公司,分公司处在不同的区域。...2016-01-27
- 这篇文章主要介绍了Tomcat配置及如何在Eclipse中启动,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下...2021-02-04
- 如果我们需要安培Laravel4的话最php最低要求要在php5.3.7版本并且我们需要把mcrypt与openss这两个扩展开启才可以,具体步骤我们参考下文。 前面我们介绍我了 com...2016-11-25
解决springboot使用logback日志出现LOG_PATH_IS_UNDEFINED文件夹的问题
这篇文章主要介绍了解决springboot使用logback日志出现LOG_PATH_IS_UNDEFINED文件夹的问题,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-04-28- 这篇文章主要为大家详细介绍了SpringBoot实现excel文件生成和下载,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2021-02-09
详解Maven profile配置管理及激活profile的几种方式
这篇文章主要介绍了详解Maven profile配置管理及激活profile的几种方式,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-01-26- 这篇文章主要介绍了详解springBoot启动时找不到或无法加载主类解决办法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2020-09-16
- 这篇文章主要介绍了SpringBoot集成Redis实现消息队列的方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-02-10
- 这篇文章主要介绍了IDEA如何添加配置文件到classpath中,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下...2020-09-19
- 通常php.ini的位置在:复制代码 代码如下:/etc目录下或/usr/local/lib目录下。如果你还是找不到php.ini或者找到了php.ini修改后不生效(其实是没找对),请使用如下办法:1.新建php文件,写入如下代码复制代码 代码如下:<?phpe...2014-05-31
- 以下就是部署PHP时的4个配置修改说明,大家一个一个进行学习研究。1、short_open_tag 是什么呢? 决定是否允许使用代码开始标志的缩写形式(<? ?> )。如果要和 XML 结合使用PHP,可以禁用此选项以便于嵌入使用<?x...2015-10-21
- 这篇文章主要介绍了解决Springboot get请求是参数过长的情况,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-09-17
Spring Boot项目@RestController使用重定向redirect方式
这篇文章主要介绍了Spring Boot项目@RestController使用重定向redirect方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教...2021-09-02- 这篇文章主要介绍了Springboot+TCP监听服务器搭建过程,本文通过图文并茂的形式给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下...2020-10-28
- 这篇文章主要介绍了springBoot 项目排除数据库启动方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教...2021-09-10
华为畅享20Pro配置怎么样?华为畅享20Pro参数配置分析
华为畅享20Pro配置怎么样?对于即将上市的华为畅享20 Pro手机,很多的网友们也是相当关注的,大家都想要知道这款华为畅享20 Pro手机的配置到底怎么样,赶紧看看吧...2020-06-29- 在使用vue-router的项目中,实例化VueRouter是其配置选项routes该选项指定路由与视图的组件的关系或者路由与其他路由的关系,Router配置选项中是其中最重要的配置。本文就详细的介绍一下...2021-10-25
详解SpringBoot之访问静态资源(webapp...)
这篇文章主要介绍了详解SpringBoot之访问静态资源(webapp...),文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2020-09-14- 这篇文章主要介绍了SpringBoot接口接收json参数解析,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教...2021-10-19