最近因?yàn)轫?xiàng)目需要,接觸了shiro。新手入門
發(fā)現(xiàn)權(quán)限攔截失效,
一直以為是以為授權(quán)和DB的問題
研究了一個(gè)下午,終于發(fā)現(xiàn)了問題所在
我的訪問路徑?jīng)]有寫前面的斜杠!!,而DB中的資源路徑是可以省略的,崩潰了吧
但是問題來了,為什么在其他地方可以忽略掉前面的小斜杠呢?
經(jīng)過幾分鐘的搗鼓發(fā)現(xiàn),在springboot中,不論是thymeleaf的模板也好(我用的thymeleaf),還是后端代碼也好,底層會(huì)自動(dòng)補(bǔ)全這個(gè)斜杠
問題解決!!
補(bǔ)充知識(shí):SpringBoot整合shiro的一個(gè)完整的小案例
SpringBoot整合配置版的shiro很簡(jiǎn)單,邏輯清
首先在pom.xml的配置如下,shiro使用緩存ehcache
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
< 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
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
|
@Configuration public class ShiroConfig { @Bean public ShiroFilterFactoryBean shirFilter(DefaultWebSecurityManager securityManager) { ShiroFilterFactoryBean shiroFilter = new ShiroFilterFactoryBean(); // 必須設(shè)置 SecurityManager shiroFilter.setSecurityManager(securityManager); // 攔截器 Map<String, String> filterChainDefinitionMap = new LinkedHashMap<String, String>(); // 設(shè)置login URL shiroFilter.setLoginUrl( "/login" ); // 登錄成功后要跳轉(zhuǎn)的鏈接 shiroFilter.setSuccessUrl( "/main" ); filterChainDefinitionMap.put( "/webjars/**" , "anon" ); filterChainDefinitionMap.put( "/druid/**" , "anon" ); //靜態(tài)資源的處理 filterChainDefinitionMap.put( "/js/**" , "anon" ); filterChainDefinitionMap.put( "/css/**" , "anon" ); filterChainDefinitionMap.put( "/asserts/**" , "anon" ); filterChainDefinitionMap.put( "/fonts/**" , "anon" ); filterChainDefinitionMap.put( "/images/**" , "anon" ); // 退出系統(tǒng)的過濾器 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如下配置
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
|
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( "用戶不存在!" ); } // 靠用戶名從數(shù)據(jù)庫查詢?cè)撚脩舻娜啃畔?/code> User user = userService.getByName(username); // 傳入:用戶名,加密后的密碼,鹽值,該realm的名字,加密算法和加密次數(shù)在已經(jīng)在配置文件中指定 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. 利用登錄的用戶的信息來..當(dāng)前用戶的角色或權(quán)限(可能需要查詢數(shù)據(jù)庫) Set<String> roles = new HashSet<String>(); roles.add( "user" ); if ( "admin" .equals(principal)) { roles.add( "admin" ); } // 3. 創(chuàng)建 SimpleAuthorizationInfo, 并設(shè)置其 reles 屬性 SimpleAuthorizationInfo info = new SimpleAuthorizationInfo(roles); // 4. 返回 SimpleAuthorizationInfo 對(duì)象. return info; } } |
由于我做的平臺(tái)只有一個(gè)管理員就不寫注冊(cè)了,這時(shí)手動(dòng)算出一個(gè)admin用戶的密碼
1
2
3
4
5
|
public static void main(String[] args) { Object result = new SimpleHash( "MD5" , "123456" ,ByteSource.Util.bytes( "admin" ), 1024 ); System.out.println(result); } |
最后寫登錄的Controller
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
|
@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 對(duì)象 UsernamePasswordToken token = new UsernamePasswordToken(username, password); // 設(shè)置為rememberme token.setRememberMe( true ); try { // 執(zhí)行登錄. currentUser.login(token); } // 所有認(rèn)證時(shí)異常的父類 catch (AuthenticationException ae) { map.put( "password" , "輸入的用戶名或密碼錯(cuò)誤" ); log.info( "登錄失敗: " + ae.getMessage()); return "login" ; } } if (!session.getAttribute( "code" ).equals(kaptcha)) { map.put( "kaptcha" , "輸入的驗(yàn)證碼錯(cuò)誤" ); return "login" ; } session.setAttribute( "loginUser" , "user" ); return "main" ; } } |
以上這篇解決springboot+shiro 權(quán)限攔截失效的問題就是小編分享給大家的全部?jī)?nèi)容了,希望能給大家一個(gè)參考,也希望大家多多支持服務(wù)器之家。
原文鏈接:https://blog.csdn.net/qq_41247335/article/details/105319266