最近因为项目需要,接触了shiro。新手入门
发现权限拦截失效,
一直以为是以为授权和DB的问题
研究了一个下午,终于发现了问题所在
我的访问路径没有写前面的斜杠!!,而DB中的资源路径是可以省略的,崩溃了吧
但是问题来了,为什么在其他地方可以忽略掉前面的小斜杠呢?
经过几分钟的捣鼓发现,在springboot中,不论是thymeleaf的模板也好(我用的thymeleaf),还是后端代码也好,底层会自动补全这个斜杠
问题解决!!
补充知识:SpringBoot整合shiro的一个完整的小案例
SpringBoot整合配置版的shiro很简单,逻辑清
首先在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(); // 必须设置 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如下配置
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( "用户不存在!" ); } // 靠用户名从数据库查询该用户的全部信息 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用户的密码
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 对象 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 权限拦截失效的问题就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持服务器之家。
原文链接:https://blog.csdn.net/qq_41247335/article/details/105319266