解決springboot+shiro 權(quán)限攔截失效的問(wèn)題
最近因?yàn)轫?xiàng)目需要,接觸了shiro。新手入門
發(fā)現(xiàn)權(quán)限攔截失效,
一直以為是以為授權(quán)和DB的問(wèn)題
研究了一個(gè)下午,終于發(fā)現(xiàn)了問(wèn)題所在

我的訪問(wèn)路徑?jīng)]有寫前面的斜杠??!,而DB中的資源路徑是可以省略的,崩潰了吧
但是問(wèn)題來(lái)了,為什么在其他地方可以忽略掉前面的小斜杠呢?
經(jīng)過(guò)幾分鐘的搗鼓發(fā)現(xiàn),在springboot中,不論是thymeleaf的模板也好(我用的thymeleaf),還是后端代碼也好,底層會(huì)自動(dòng)補(bǔ)全這個(gè)斜杠
問(wèn)題解決!!
補(bǔ)充知識(shí):SpringBoot整合shiro的一個(gè)完整的小案例
SpringBoot整合配置版的shiro很簡(jiǎn)單,邏輯清
首先在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();
// 必須設(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)的過(guò)濾器
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("用戶不存在!");
}
// 靠用戶名從數(shù)據(jù)庫(kù)查詢?cè)撚脩舻娜啃畔?
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 中來(lái)獲取登錄用戶的信息
Object principal = principals.getPrimaryPrincipal();
// 2. 利用登錄的用戶的信息來(lái)..當(dāng)前用戶的角色或權(quán)限(可能需要查詢數(shù)據(jù)庫(kù))
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用戶的密碼
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 對(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)限攔截失效的問(wèn)題就是小編分享給大家的全部?jī)?nèi)容了,希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
- SpringBoot+Shiro+Redis+Mybatis-plus 實(shí)戰(zhàn)項(xiàng)目及問(wèn)題小結(jié)
- Springboot和bootstrap實(shí)現(xiàn)shiro權(quán)限控制配置過(guò)程
- SpringBoot + Shiro前后端分離權(quán)限
- SpringBoot 整合 Shiro 密碼登錄與郵件驗(yàn)證碼登錄功能(多 Realm 認(rèn)證)
- Springboot shiro認(rèn)證授權(quán)實(shí)現(xiàn)原理及實(shí)例
- 基于springboot實(shí)現(xiàn)整合shiro實(shí)現(xiàn)登錄認(rèn)證以及授權(quán)過(guò)程解析
- SpringBoot整合Shiro實(shí)現(xiàn)登錄認(rèn)證的方法
- Springboot+Shiro+Mybatis+mysql實(shí)現(xiàn)權(quán)限安全認(rèn)證的示例代碼
相關(guān)文章
Java深入講解AWT實(shí)現(xiàn)事件處理流程
AWT的事件處理是一種委派式事件處理方式:普通組件(事件源)將整個(gè)事件處理委托給特定的對(duì)象(事件監(jiān)聽器);當(dāng)該事件源發(fā)生指定的事件時(shí),就通知所委托的事件監(jiān)聽器,由事件監(jiān)聽器來(lái)處理這個(gè)事件2022-04-04
一文詳細(xì)講解Java時(shí)間格式轉(zhuǎn)換
這篇文章主要介紹了Java時(shí)間格式轉(zhuǎn)換的相關(guān)資料,文中詳細(xì)介紹了SimpleDateFormat(適用于Java8之前)和java.time(適用于Java8及之后)的用法,需要的朋友可以參考下2024-12-12
IDEA中Javaweb項(xiàng)目圖片加載不出來(lái)解決方案
在IDEA中能夠正常的預(yù)覽到圖片,但是在生成項(xiàng)目的war包時(shí),項(xiàng)目的目錄結(jié)構(gòu)卻會(huì)發(fā)生變化,所以無(wú)法訪問(wèn)圖片,本文主要介紹了IDEA中Javaweb項(xiàng)目圖片加載不出來(lái)解決方案,感興趣的可以了解一下2023-10-10
SpringSecurity?用戶帳號(hào)已被鎖定的問(wèn)題及解決方法
這篇文章主要介紹了SpringSecurity?用戶帳號(hào)已被鎖定,本文給大家分享問(wèn)題原因及解決方式,需要的朋友可以參考下2023-12-12
SpringBoot實(shí)現(xiàn)WebSocket的示例代碼
這篇文章主要為大家詳細(xì)介紹了SpringBoot實(shí)現(xiàn)WebSocket的相關(guān)知識(shí),文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2024-11-11
Springboot編寫CRUD時(shí)訪問(wèn)對(duì)應(yīng)數(shù)據(jù)函數(shù)返回null的問(wèn)題及解決方法
我在學(xué)習(xí)springboot,其中在編寫CRUD時(shí)發(fā)現(xiàn)訪問(wèn)數(shù)據(jù)的函數(shù)執(zhí)行下去返回值是null但是其它部分正常,這篇文章主要介紹了Springboot在編寫CRUD時(shí),訪問(wèn)對(duì)應(yīng)數(shù)據(jù)函數(shù)返回null,需要的朋友可以參考下2024-02-02
List對(duì)象去重和按照某個(gè)字段排序的實(shí)現(xiàn)方法
下面小編就為大家?guī)?lái)一篇List對(duì)象去重和按照某個(gè)字段排序的實(shí)現(xiàn)方法。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-05-05

