国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

spring boot集成shiro

2019-11-08 03:01:07
字體:
來源:轉載
供稿:網友

添加shiro依賴

<dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-sPRing</artifactId> <version>1.3.2</version></dependency>

編寫shiro configuration文件ShiroConfig.java

package com.ls.shiro;import org.apache.shiro.authc.credential.HashedCredentialsMatcher;import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;import org.apache.shiro.spring.web.ShiroFilterFactoryBean;import org.apache.shiro.web.mgt.DefaultWebSecurityManager;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.apache.shiro.mgt.SecurityManager;import java.util.LinkedHashMap;import java.util.Map;/** * <p></p> * Created by zhezhiyong@163.com on 2017/2/17. */@Configurationpublic class ShiroConfig { /** * ShiroFilterFactoryBean 處理攔截資源文件問題。 * 注意:單獨一個ShiroFilterFactoryBean配置是或報錯的,以為在 * 初始化ShiroFilterFactoryBean的時候需要注入:SecurityManager * <p> * Filter Chain定義說明 * 1、一個URL可以配置多個Filter,使用逗號分隔 * 2、當設置多個過濾器時,全部驗證通過,才視為通過 * 3、部分過濾器可指定參數,如perms,roles */ @Bean public ShiroFilterFactoryBean shirFilter(SecurityManager securityManager) { ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean(); // 必須設置 SecurityManager shiroFilterFactoryBean.setSecurityManager(securityManager); //攔截器. Map<String, String> filterChainDefinitionMap = new LinkedHashMap<>(); //配置退出 過濾器,其中的具體的退出代碼Shiro已經替我們實現了 filterChainDefinitionMap.put("/logout", "logout"); //<!-- 過濾鏈定義,從上向下順序執行,一般將 /**放在最為下邊 -->:這是一個坑呢,一不小心代碼就不好使了; //<!-- authc:所有url都必須認證通過才可以訪問; anon:所有url都都可以匿名訪問--> filterChainDefinitionMap.put("/static/**", "anon"); filterChainDefinitionMap.put("/**", "authc"); // 如果不設置默認會自動尋找Web工程根目錄下的"/login.jsp"頁面 shiroFilterFactoryBean.setLoginUrl("/login"); // 登錄成功后要跳轉的鏈接 shiroFilterFactoryBean.setSuccessUrl("/"); //未授權界面; shiroFilterFactoryBean.setUnauthorizedUrl("/403"); shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap); return shiroFilterFactoryBean; } @Bean public SecurityManager securityManager() { DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager(); securityManager.setRealm(shiroRealm()); return securityManager; } /** * 身份認證realm; * (這個需要自己寫,賬號密碼校驗;權限等) */ @Bean public ShiroRealm shiroRealm() { ShiroRealm shiroRealm = new ShiroRealm(); shiroRealm.setCredentialsMatcher(hashedCredentialsMatcher()); return shiroRealm; } /** * 憑證匹配器 * (由于我們的密碼校驗交給Shiro的SimpleAuthenticationInfo進行處理了 * 所以我們需要修改下doGetAuthenticationInfo中的代碼; * ) */ @Bean public HashedCredentialsMatcher hashedCredentialsMatcher() { HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher(); hashedCredentialsMatcher.setHashAlgorithmName("md5");//散列算法:這里使用MD5算法; hashedCredentialsMatcher.setHashIterations(2);//散列的次數,比如散列兩次,相當于 md5(md5("")); hashedCredentialsMatcher.setStoredCredentialsHexEncoded(true);//默認true return hashedCredentialsMatcher; } /** * 開啟shiro aop注解支持. * 使用代理方式;所以需要開啟代碼支持; */ @Bean public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager) { AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor(); authorizationAttributeSourceAdvisor.setSecurityManager(securityManager); return authorizationAttributeSourceAdvisor; }}

編寫自定義RealmShiroRealm.java

package com.ls.shiro;import com.github.pagehelper.util.StringUtil;import com.ls.model.Permission;import com.ls.model.Role;import com.ls.model.User;import com.ls.service.PermissionService;import com.ls.service.RoleService;import com.ls.service.UserService;import com.ls.util.StringUtils;import org.apache.shiro.SecurityUtils;import org.apache.shiro.authc.AuthenticationException;import org.apache.shiro.authc.AuthenticationInfo;import org.apache.shiro.authc.AuthenticationToken;import org.apache.shiro.authc.SimpleAuthenticationInfo;import org.apache.shiro.authz.AuthorizationException;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.apache.shiro.subject.Subject;import org.apache.shiro.util.ByteSource;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import javax.annotation.Resource;import java.util.ArrayList;import java.util.List;import java.util.stream.Collectors;import static freemarker.ext.servlet.FreemarkerServlet.KEY_SESSION;/** * <p></p> * Created by zhezhiyong@163.com on 2017/2/17. */public class ShiroRealm extends AuthorizingRealm { private Logger logger = LoggerFactory.getLogger(getClass()); @Resource private UserService userService; @Resource private RoleService roleService; @Resource private PermissionService permissionService; /** * 登錄驗證 * * @param token 是用來驗證用戶身份 */ @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException { logger.debug("登錄驗證"); //獲取用戶的輸入的賬號. String loginName = String.valueOf(token.getPrincipal()); String passWord = new String((char[]) token.getCredentials()); if (StringUtils.isEmpty(loginName)) { throw new AuthenticationException("用戶名或密碼錯誤."); } //通過username從數據庫中查找 User對象,如果找到,沒找到. //實際項目中,這里可以根據實際情況做緩存,如果不做,Shiro自己也是有時間間隔機制,2分鐘內不會重復執行該方法 User user = userService.findByLoginName(loginName); if (user == null) { return null; } this.setSession(KEY_SESSION, user); /* * 獲取權限信息:這里沒有進行實現, * 請自行根據UserInfo,Role,Permission進行實現; * 獲取之后可以在前端for循環顯示所有鏈接; */ //userInfo.setPermissions(userService.findPermissions(user)); //賬號判斷; //加密方式; //交給AuthenticatingRealm使用CredentialsMatcher進行密碼匹配,如果覺得人家的不好可以自定義實現 SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo( user.getLoginName(), //用戶名 user.getPassword(), //密碼 ByteSource.Util.bytes(user.getCredentialsSalt()),//salt=username+salt getName() //realm name ); //明文: 若存在,將此用戶存放到登錄認證info中,無需自己做密碼對比,Shiro會為我們進行密碼對比校驗// SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(// user.getLoginName(), //用戶名// user.getPassword(), //密碼// getName() //realm name// ); return authenticationInfo; } /** * 此方法調用 hasRole,haspermission的時候才會進行回調. * <p> * 權限信息.(授權): * 1、如果用戶正常退出,緩存自動清空; * 2、如果用戶非正常退出,緩存自動清空; * 3、如果我們修改了用戶的權限,而用戶不退出系統,修改的權限無法立即生效。 * (需要手動編程進行實現;放在service進行調用) * 在權限修改后調用realm中的方法,realm已經由spring管理,所以從spring中獲取realm實例, * 調用clearCached方法; * :Authorization 是授權訪問控制,用于對用戶進行的操作授權,證明該用戶是否允許進行當前操作,如訪問某個鏈接,某個資源文件等。 */ @Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) { /* * 當沒有使用緩存的時候,不斷刷新頁面的話,這個代碼會不斷執行, * 當其實沒有必要每次都重新設置權限信息,所以我們需要放到緩存中進行管理; * 當放到緩存中時,這樣的話,doGetAuthorizationInfo就只會執行一次了, * 緩存過期之后會再次執行。 */ logger.debug("shiro 授權"); SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo(); // 獲取當前登錄的用戶名,等價于(String)principals.fromRealm(this.getName()).iterator().next() // String currentUsername = // (String)super.getAvailablePrincipal(principals); String loginName = String.valueOf(principals.getPrimaryPrincipal()); if (StringUtil.isEmpty(loginName)) { throw new AuthorizationException(); } final User user = userService.findByLoginName(loginName); final Role role = roleService.findByUserId(user.getId()); List<Permission> permissionList = permissionService.findByRoleId(role.getId()); authorizationInfo.addRole(role.getRole()); List<String> pList = permissionList.stream().map(Permission::getPermission).collect(Collectors.toList()); authorizationInfo.addStringPermissions(pList);// for (Role role : roles) {// // 添加角色// authorizationInfo.addRole(role.getSign());// final List<Permission> permissions = permissionService.getPermissionsByRoleId(role.getId());// for (Permission permission : permissions) {// // 添加權限// authorizationInfo.addStringPermission(permission.getSign());// }// } return authorizationInfo; } /** * 將一些數據放到ShiroSession中,以便于其它地方使用 * <p> * 比如Controller,使用時直接用HttpSession.getAttribute(key)就可以取到 */ private void setSession(Object key, Object value) { Subject currentUser = SecurityUtils.getSubject(); if (null != currentUser) { Session session = currentUser.getSession(); logger.debug("Session默認超時時間為[" + session.getTimeout() + "]毫秒"); session.setAttribute(key, value); } }}

shiro密碼加密

package com.ls.util;import org.apache.shiro.crypto.hash.SimpleHash;import org.apache.shiro.util.ByteSource;/** * <p></p> * Created by zhezhiyong@163.com on 2017/2/18. */public class CommonUtils { /** * 獲取shiro加密,進行MD5 2次加密 * @param password * @param salt * @return */ public static String getEncryptPsw(String password, String salt) { return new SimpleHash("md5", password, ByteSource.Util.bytes(salt), 2).toHex(); }}

使用shiro權限

如果沒有權限,會報異常org.apache.shiro.authz.UnauthorizedException: Subject does not have permission [user:view]

在控制器上添加注釋@RequiresPermissions("user:view")

osc源碼地址

osc源碼地址,如果你覺得對你有幫助請star,謝謝


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 阿城市| 景东| 静海县| 灵丘县| 东乡县| 花莲县| 新营市| 凌海市| 沂水县| 达拉特旗| 金堂县| 莎车县| 应城市| 汉川市| 方山县| 伊春市| 靖边县| 荥经县| 洛阳市| 库尔勒市| 合作市| 海盐县| 雷山县| 鄂尔多斯市| 扶沟县| 若尔盖县| 平顶山市| 湘潭县| 盱眙县| 东阿县| 花垣县| 桐庐县| 泗洪县| 城步| 镇雄县| 新蔡县| 巩义市| 措美县| 顺义区| 曲周县| 周至县|