您好,登錄后才能下訂單哦!
今天小編給大家分享一下SpringBoot怎么整合Shiro的相關知識點,內容詳細,邏輯清晰,相信大部分人都還太了解這方面的知識,所以分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后有所收獲,下面我們一起來了解一下吧。
我們將我們的SpringBoot應用整合shiro,主要目的就是讓shiro幫我們處理認證和授權的相關內容。也就是說,我們需要讓shiro接管我們SpringBoot應用的會話。讓用戶的每一次請求都經過shiro進行認證和授權。因此,我們需要將用戶請求攔截下來轉發給shiro處理,這個攔截器是shiro提供的,ShiroFilter
。
步驟:
用戶通過客戶端(瀏覽器、手機App、小程序)發起請求
ShiroFilter攔截請求并判斷請求訪問的資源是否為受保護資源:
2.1 是,則執行步驟3
2.2 不是,則直接放行
判斷用戶是否已通過認證:
3.1 是 ,則執行步驟4
3.2 否,將用戶請求重定向到認證頁面,讓用戶先認證
獲取用戶權限信息和訪問資源所需要的權限信息進行比對:
4.1 用戶具備訪問權限,則放行
4.2 用戶不具備權限,返回403的相應提示
我們通過MySQL保存我們的認證和權限的相關數據。采用用戶-角色-權限模型實現動態管理用戶權限信息。
我們將系統當中的菜單、按鈕、后端接口都抽象成系統的資源數據。以下是數據庫表的設計:
文末提供sql腳本的下載。
創建一個SpringBoot的web應用,并引入如下依賴
<dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-spring-boot-web-starter</artifactId> <version>1.6.0</version> </dependency>
這里代碼就省略了,不影響理解,完整代碼可以從文末提供的方式中下載。
/**自定義Realm,使用mysql數據源 * @author 賴柄灃 bingfengdev@aliyun.com * @version 1.0 * @date 2020/10/6 9:09 */ public class MySQLRealm extends AuthorizingRealm { @Autowired private IUserService userService; @Autowired private IRoleService roleService; @Autowired private IResourceService resourceService; /** * 授權 * @param principals * @return */ @Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) { String username = (String) principals.getPrimaryPrincipal(); List<Role> roleList = roleService.findByUsername(username); SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo(); for (Role role : roleList) { authorizationInfo.addRole(role.getRoleName()); } List<Long> roleIdList = new ArrayList<>(); for (Role role : roleList) { roleIdList.add(role.getRoleId()); } List<Resource> resourceList = resourceService.findByRoleIds(roleIdList); for (Resource resource : resourceList) { authorizationInfo.addStringPermission(resource.getResourcePermissionTag()); } return authorizationInfo; } /** * 認證 * @param token * @return * @throws AuthenticationException */ @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException { if(token==null){ return null; } String principal = (String) token.getPrincipal(); User user = userService.findByUsername(principal); SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(user.getUsername(), user.getPassword(), ByteSource.Util.bytes(user.getSalt()), getName()); return simpleAuthenticationInfo; } }
shiro中的Realm對象充當了認證、授權數信息的據源作用。關于更多自定義Realm的內容請參考我的另一篇文章《Shiro入門學習—使用自定義Realm完成認證|練氣中期》 。
/**shiro配置類 * @author 賴柄灃 bingfengdev@aliyun.com * @version 1.0 * @date 2020/10/6 9:11 */ @Configuration public class ShiroConfig { /** * 創建ShiroFilter攔截器 * @return ShiroFilterFactoryBean */ @Bean(name = "shiroFilterFactoryBean") public ShiroFilterFactoryBean getShiroFilterFactoryBean(DefaultWebSecurityManager securityManager){ ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean(); shiroFilterFactoryBean.setSecurityManager(securityManager); //配置不攔截路徑和攔截路徑,順序不能反 HashMap<String, String> map = new HashMap<>(5); map.put("/authc/**","anon"); map.put("/login.html","anon"); map.put("/js/**","anon"); map.put("/css/**","anon"); map.put("/**","authc"); shiroFilterFactoryBean.setFilterChainDefinitionMap(map); //覆蓋默認的登錄url shiroFilterFactoryBean.setLoginUrl("/authc/unauthc"); return shiroFilterFactoryBean; } @Bean public Realm getRealm(){ //設置憑證匹配器,修改為hash憑證匹配器 HashedCredentialsMatcher myCredentialsMatcher = new HashedCredentialsMatcher(); //設置算法 myCredentialsMatcher.setHashAlgorithmName("md5"); //散列次數 myCredentialsMatcher.setHashIterations(512); MySQLRealm realm = new MySQLRealm(); realm.setCredentialsMatcher(myCredentialsMatcher); return realm; } /** * 創建shiro web應用下的安全管理器 * @return DefaultWebSecurityManager */ @Bean public DefaultWebSecurityManager getSecurityManager(Realm realm){ DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager(); securityManager.setRealm(realm); SecurityUtils.setSecurityManager(securityManager); return securityManager; } }
在編寫shiro配置類這一步,需要大家注意的是,因為我們使用的是md5+salt+hash加密我們的密碼,因此要換掉默認的憑證匹配器CredentialsMatcher對象,對于這部分的內容請參考我的另一篇文章《shiro入門學習–使用MD5和salt進行加密|練氣后期》 。
/**認證請求參數 * @author 賴柄灃 bingfengdev@aliyun.com * @version 1.0 * @date 2020/10/7 15:12 */ @Data public class LoginVO implements Serializable { private String username; private String password; }
/**認證模塊 * @author 賴柄灃 bingfengdev@aliyun.com * @version 1.0 * @date 2020/10/6 10:07 */ @RestController @RequestMapping("/authc") public class AuthcController { @Autowired private AuthcService authcService; @PostMapping("/login") public boolean login(@RequestBody LoginVO loginVO){ return authcService.login(loginVO); } @GetMapping("/unauthc") public String unauthc(){ return "請先登錄"; } }
/** * @author 賴柄灃 bingfengdev@aliyun.com * @version 1.0 * @date 2020/10/7 15:15 */ @Service public class AuthcServiceImpl implements AuthcService { @Override public boolean login(LoginVO loginVO) throws AuthenticationException { if (loginVO==null){ return false; } if (loginVO.getUsername()==null||"".equals(loginVO.getUsername())){ return false; } if (loginVO.getPassword() == null || "".equals(loginVO.getPassword())){ return false; } Subject subject = SecurityUtils.getSubject(); UsernamePasswordToken token = new UsernamePasswordToken(loginVO.getUsername(), loginVO.getPassword()); subject.login(token); return true; } }
/**產品模塊 * @author 賴柄灃 bingfengdev@aliyun.com * @version 1.0 * @date 2020/10/6 10:14 */ @RestController @RequestMapping("/product") public class ProductController { @RequiresPermissions("product:get") @GetMapping("/get/list") public String getProductList() { return "productList"; } @RequiresPermissions("product:delete") @GetMapping("/delete") public String deleteProduct() { return "刪除產品數據"; } }
對于注解實現訪問控制,shiro主要有兩個注解:RequiresPermissions和RequiresRoles。均可以用在類和方法上。具體用在哪可以根據自己的系統權限劃分粒度決定。
對于這兩個注解,有兩個參數:
value
:分別對應permission的權限字符串值和role的角色名稱;
logical
:邏輯運算符。這是一個枚舉類型,有AND
和OR
兩個值。當使用AND
時表示需要滿足所有傳入的value
值,OR
表示僅需滿足一個value
即可。默認為AND
關于shiro權限(訪問控制)的更多內容,可以閱讀我的另一篇文章《shiro入門學習–授權(Authorization)|筑基初期》
默認的消息提示可以換一下。
以上就是“SpringBoot怎么整合Shiro”這篇文章的所有內容,感謝各位的閱讀!相信大家閱讀完這篇文章都有很大的收獲,小編每天都會為大家更新不同的知識,如果還想學習更多的知識,請關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。