SpringBoot配置shiro安全框架的實現
首先引入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 */@Configurationpublic 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管理 使用redissecurityManager.setSessionManager(sessionManager());// 自定義緩存實現 使用redissecurityManager.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 * */@Componentpublic 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內容請搜索好吧啦網以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持好吧啦網!
相關文章:
