解決springboot+shiro 許可權攔截失效的問題
阿新 • • 發佈:2020-09-27
最近因為專案需要,接觸了shiro。新手入門
發現許可權攔截失效,
一直以為是以為授權和DB的問題
研究了一個下午,終於發現了問題所在
我的訪問路徑沒有寫前面的斜槓!!,而DB中的資源路徑是可以省略的,崩潰了吧
但是問題來了,為什麼在其他地方可以忽略掉前面的小斜槓呢?
經過幾分鐘的搗鼓發現,在springboot中,不論是thymeleaf的模板也好(我用的thymeleaf),還是後端程式碼也好,底層會自動補全這個斜槓
問題解決!!
補充知識:SpringBoot整合shiro的一個完整的小案例
SpringBoot整合配置版的shiro很簡單,邏輯清
首先在pom.xml的配置如下,shiro使用快取ehcache
<dependency> <groupId>net.sf.ehcache</groupId> <artifactId>ehcache</artifactId> <version>2.10.4</version> </dependency> <!-- shiro spring. --> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-core</artifactId> <version>1.2.2</version> </dependency> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-spring</artifactId> <version>1.2.2</version> </dependency> <!-- shiro ehcache --> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-ehcache</artifactId> <version>1.2.2</version> </dependency>
接著配置shiro
@Configuration public class ShiroConfig { @Bean public ShiroFilterFactoryBean shirFilter(DefaultWebSecurityManager securityManager) { ShiroFilterFactoryBean shiroFilter = new ShiroFilterFactoryBean(); // 必須設定 SecurityManager shiroFilter.setSecurityManager(securityManager); // 攔截器 Map<String,String> filterChainDefinitionMap = new LinkedHashMap<String,String>(); // 設定login URL shiroFilter.setLoginUrl("/login"); // 登入成功後要跳轉的連結 shiroFilter.setSuccessUrl("/main"); filterChainDefinitionMap.put("/webjars/**","anon"); filterChainDefinitionMap.put("/druid/**","anon"); //靜態資源的處理 filterChainDefinitionMap.put("/js/**","anon"); filterChainDefinitionMap.put("/css/**","anon"); filterChainDefinitionMap.put("/asserts/**","anon"); filterChainDefinitionMap.put("/fonts/**","anon"); filterChainDefinitionMap.put("/images/**","anon"); // 退出系統的過濾器 filterChainDefinitionMap.put("/logout","logout"); filterChainDefinitionMap.put("/login","anon"); filterChainDefinitionMap.put("/kaptcha","anon"); filterChainDefinitionMap.put("/**","authc"); shiroFilter.setFilterChainDefinitionMap(filterChainDefinitionMap); return shiroFilter; } @Bean public HashedCredentialsMatcher hashedCredentialsMatcher() { HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher(); hashedCredentialsMatcher.setHashAlgorithmName("MD5"); hashedCredentialsMatcher.setHashIterations(1024); return hashedCredentialsMatcher; } @Bean public ShiroRealm shiroRealm(HashedCredentialsMatcher hashedCredentialsMatcher) { ShiroRealm shiroRealm = new ShiroRealm(); shiroRealm.setCredentialsMatcher(hashedCredentialsMatcher); return shiroRealm; } //shiro使用快取ehcachae @Bean public EhCacheManager ehCacheManager() { EhCacheManager ehCacheManager = new EhCacheManager(); ehCacheManager.setCacheManagerConfigFile("classpath:ehcache.xml"); return ehCacheManager; } @Bean("sessionManager") public SessionManager sessionManager(){ DefaultWebSessionManager sessionManager = new DefaultWebSessionManager(); sessionManager.setSessionValidationSchedulerEnabled(true); sessionManager.setSessionIdCookieEnabled(true); return sessionManager; } @Bean("securityManager") public DefaultWebSecurityManager securityManager(ShiroRealm shiroRealm,SessionManager sessionManager) { DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager(); securityManager.setRealm(shiroRealm); securityManager.setSessionManager(sessionManager); return securityManager; } @Bean("lifecycleBeanPostProcessor") public LifecycleBeanPostProcessor lifecycleBeanPostProcessor() { return new LifecycleBeanPostProcessor(); } @Bean public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() { DefaultAdvisorAutoProxyCreator proxyCreator = new DefaultAdvisorAutoProxyCreator(); proxyCreator.setProxyTargetClass(true); return proxyCreator; } @Bean public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager) { AuthorizationAttributeSourceAdvisor advisor = new AuthorizationAttributeSourceAdvisor(); advisor.setSecurityManager(securityManager); return advisor; } }
在配置中提到的realm如下配置
public class ShiroRealm extends AuthorizingRealm { @Autowired private UserService userService; @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException { UsernamePasswordToken upToken = (UsernamePasswordToken) token; // 取出表單使用者名稱 String username = upToken.getUsername(); // 查詢是否有該使用者 if (userService.getByName(username) == null) { throw new UnknownAccountException("使用者不存在!"); } // 靠使用者名稱從資料庫查詢該使用者的全部資訊 User user = userService.getByName(username); // 傳入:使用者名稱,加密後的密碼,鹽值,該realm的名字,加密演算法和加密次數在已經在配置檔案中指定 SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(username,user.getPassword(),ByteSource.Util.bytes(username),getName()); return info; } @Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) { // 1. 從 PrincipalCollection 中來獲取登入使用者的資訊 Object principal = principals.getPrimaryPrincipal(); // 2. 利用登入的使用者的資訊來..當前使用者的角色或許可權(可能需要查詢資料庫) Set<String> roles = new HashSet<String>(); roles.add("user"); if ("admin".equals(principal)) { roles.add("admin"); } // 3. 建立 SimpleAuthorizationInfo,並設定其 reles 屬性 SimpleAuthorizationInfo info = new SimpleAuthorizationInfo(roles); // 4. 返回 SimpleAuthorizationInfo 物件. return info; } }
由於我做的平臺只有一個管理員就不寫註冊了,這時手動算出一個admin使用者的密碼
public static void main(String[] args) { Object result = new SimpleHash("MD5","123456",ByteSource.Util.bytes("admin"),1024); System.out.println(result); }
最後寫登入的Controller
@Controller public class LoginController { // 處理登入邏輯 @PostMapping("/login") public String login(String username,String password,String kaptcha,HttpSession session,Map<String,Object> map) { Subject currentUser = SecurityUtils.getSubject(); if (!currentUser.isAuthenticated()) { // 把使用者名稱和密碼封裝為 UsernamePasswordToken 物件 UsernamePasswordToken token = new UsernamePasswordToken(username,password); // 設定為rememberme token.setRememberMe(true); try { // 執行登入. currentUser.login(token); } // 所有認證時異常的父類 catch (AuthenticationException ae) { map.put("password","輸入的使用者名稱或密碼錯誤"); log.info("登入失敗: " + ae.getMessage()); return "login"; } } if (!session.getAttribute("code").equals(kaptcha)) { map.put("kaptcha","輸入的驗證碼錯誤"); return "login"; } session.setAttribute("loginUser","user"); return "main"; } }
以上這篇解決springboot+shiro 許可權攔截失效的問題就是小編分享給大家的全部內容了,希望能給大家一個參考,也希望大家多多支援我們。