最近研究後端的權限管理,通常兩個選擇shiro和spring security,都說shiro相對簡單,就先用他,後面在去研究spring security。html
具體的內容介紹很少介紹了,找了兩個大佬寫的博客,講的挺不錯,連接貼上java
https://segmentfault.com/a/1190000011918957web
https://www.cnblogs.com/ll409546297/p/7815409.htmlspring
而後比葫蘆畫瓢本身寫的代碼也貼上來看看,相關地方都已加上註釋數據庫
ShiroConfiguration文件的內容apache
package com.example.web.controller; import org.apache.shiro.web.mgt.DefaultWebSecurityManager; import org.apache.shiro.mgt.SecurityManager; import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor; import org.apache.shiro.spring.web.ShiroFilterFactoryBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import java.util.HashMap; import java.util.Map; @Configuration public class ShiroConfiguration { //將本身的驗證方式加入容器 @Bean public MyShiroRealm myShiroRealm() { MyShiroRealm myShiroRealm = new MyShiroRealm(); return myShiroRealm; } //權限管理,配置主要是Realm的管理認證 @Bean public SecurityManager securityManager() { DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager(); securityManager.setRealm(myShiroRealm()); return securityManager; } //Filter工廠,設置對應的過濾條件和跳轉條件 @Bean public ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager) { ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean(); shiroFilterFactoryBean.setSecurityManager(securityManager); Map<String, String> map = new HashMap<>(); //logout:登出的路由設定,調用會自動完成並跳轉到登陸頁面 // map.put("/home/logout", "logout"); //anon:對此類路由不進行驗證,login路由也不能限制 map.put("/home/index", "anon"); map.put("/home/login", "anon"); //authc:對此類路由進行驗證 map.put("/**", "authc"); shiroFilterFactoryBean.setFilterChainDefinitionMap(map); //登陸頁面的地址,沒有權限的時候會自動回到此頁面 // shiroFilterFactoryBean.setLoginUrl("/home/login"); //登陸成功後跳轉到頁面,感受沒什麼用 // shiroFilterFactoryBean.setSuccessUrl("/home/index"); //錯誤頁面,認證不經過跳轉 shiroFilterFactoryBean.setUnauthorizedUrl("/error"); return shiroFilterFactoryBean; } //加入註解的使用,不加入這個註解不生效 @Bean public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager) { AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor(); authorizationAttributeSourceAdvisor.setSecurityManager(securityManager); return authorizationAttributeSourceAdvisor; } }
MyShiroRealm文件內容segmentfault
package com.example.web.controller; 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.AuthorizationInfo; import org.apache.shiro.authz.SimpleAuthorizationInfo; import org.apache.shiro.realm.AuthorizingRealm; import org.apache.shiro.subject.PrincipalCollection; //定義此類用於登陸驗證判斷 public class MyShiroRealm extends AuthorizingRealm { //角色權限和對應權限添加 @Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) { //獲取登陸用戶名 String name = (String) principalCollection.getPrimaryPrincipal(); //查詢用戶名稱 return new SimpleAuthorizationInfo(); } //用戶認證也就是登陸信息 @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException { //獲取用戶輸入的帳號 String name = authenticationToken.getPrincipal().toString(); //經過username從數據庫中查找 User對象,若是找到,沒找到. //實際項目中,這裏能夠根據實際狀況作緩存,若是不作,Shiro本身也是有時間間隔機制,2分鐘內不會重複執行該方法 //模擬數據庫查詢出來的密碼是0 String pwd = "0"; //傳入數據庫查詢出來的數據進行驗證 //放入shiro.調用CredentialsMatcher檢驗密碼 SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(name, pwd, getName()); return simpleAuthenticationInfo; } }
而後是控制器也就是頁面的模擬狀況代碼後端
package com.example.web.controller; import org.apache.shiro.SecurityUtils; import org.apache.shiro.authc.UsernamePasswordToken; import org.apache.shiro.subject.Subject; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.CrossOrigin; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; import java.util.ArrayList; import java.util.List; @RestController @CrossOrigin public class HomeController { @Autowired HomeRepository homeRepository; @GetMapping("/home/index") public String index() { return "默認頁面,什麼操做也沒有"; } //登陸操做 @GetMapping("/home/login") public String login() { Subject subject = SecurityUtils.getSubject(); UsernamePasswordToken usernamePasswordToken = new UsernamePasswordToken("admin", "0"); //進行驗證,這裏能夠捕獲異常,而後返回對應信息 subject.login(usernamePasswordToken); return "登陸成功"; } //若是在配置哪裏配置有logout就不須要此處寫代碼 @GetMapping("/home/logout") public String logout() { Subject currentUser = SecurityUtils.getSubject(); currentUser.logout(); return "註銷成功"; } //有權限攔截的頁面 @GetMapping("/home/home") public List<Router> home() { List<Router> routers = new ArrayList<>(); Router router = new Router(); router.setPath("/index"); router.setName("index"); router.setComponent("components/index"); routers.add(router); List<Router> routers1 = homeRepository.findAll(); return routers; } }