在現代Web應用中,用戶認證和權限校驗是必不可少的功能。Spring Boot快速開發框架,提供了豐富的功能來簡化開發過程。而Shiro強大的安全框架,能夠幫助我們輕松實現用戶認證和權限校驗。本文將詳細介紹如何在Spring Boot項目中整合Shiro,并實現登錄與權限校驗功能。
Apache Shiro是一個強大且易用的Java安全框架,提供了認證、授權、加密和會話管理等功能。Shiro的設計目標是簡化應用程序的安全管理,使開發者能夠專注于業務邏輯的實現。
Spring Boot是Spring框架的一個子項目,旨在簡化Spring應用的初始搭建和開發過程。Spring Boot通過自動配置和約定優于配置的原則,使得開發者能夠快速構建獨立的、生產級別的Spring應用。
在開始整合Shiro之前,我們需要先搭建一個Spring Boot項目??梢允褂肧pring Initializr來快速生成項目骨架。
src
├── main
│ ├── java
│ │ └── com
│ │ └── example
│ │ └── demo
│ │ ├── config
│ │ ├── controller
│ │ ├── entity
│ │ ├── service
│ │ └── DemoApplication.java
│ └── resources
│ ├── static
│ ├── templates
│ └── application.properties
└── test
└── java
└── com
└── example
└── demo
在整合Shiro之前,我們需要了解Shiro的核心組件及其作用。
Subject是Shiro的核心概念,代表當前用戶的安全操作。通過Subject,我們可以執行認證、授權等操作。
SecurityManager是Shiro的核心組件,負責管理所有Subject的安全操作。它是Shiro的入口點,所有的安全操作都需要通過SecurityManager來執行。
Realm是Shiro與應用程序安全數據之間的橋梁。它負責從數據源(如數據庫、LDAP等)獲取安全數據,并將其轉換為Shiro可以理解的格式。
在Spring Boot項目中,我們需要通過配置類來配置Shiro。
@Configuration
public class ShiroConfig {
@Bean
public ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager) {
ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
shiroFilterFactoryBean.setSecurityManager(securityManager);
// 配置攔截器
Map<String, String> filterChainDefinitionMap = new LinkedHashMap<>();
filterChainDefinitionMap.put("/login", "anon");
filterChainDefinitionMap.put("/logout", "logout");
filterChainDefinitionMap.put("/**", "authc");
shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
// 配置登錄頁面
shiroFilterFactoryBean.setLoginUrl("/login");
// 配置登錄成功后的頁面
shiroFilterFactoryBean.setSuccessUrl("/index");
// 配置未授權頁面
shiroFilterFactoryBean.setUnauthorizedUrl("/403");
return shiroFilterFactoryBean;
}
@Bean
public SecurityManager securityManager(Realm realm) {
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
securityManager.setRealm(realm);
return securityManager;
}
@Bean
public Realm realm() {
return new MyRealm();
}
}
在Shiro中,我們可以通過配置攔截器來控制資源的訪問權限。常見的攔截器有:
- anon:匿名訪問,不需要認證。
- authc:需要認證才能訪問。
- logout:退出登錄。
通過shiroFilterFactoryBean.setLoginUrl()和shiroFilterFactoryBean.setUnauthorizedUrl()方法,我們可以配置登錄頁面和未授權頁面。
用戶認證是驗證用戶身份的過程。在Shiro中,我們可以通過自定義Realm來實現用戶認證。
public class MyRealm extends AuthorizingRealm {
@Autowired
private UserService userService;
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
// 授權邏輯
return null;
}
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
String username = (String) token.getPrincipal();
User user = userService.findByUsername(username);
if (user == null) {
throw new UnknownAccountException("用戶不存在");
}
return new SimpleAuthenticationInfo(user.getUsername(), user.getPassword(), getName());
}
}
在doGetAuthenticationInfo方法中,我們可以通過AuthenticationToken獲取用戶輸入的用戶名和密碼,然后與數據庫中的用戶信息進行比對。如果用戶存在且密碼正確,則返回一個SimpleAuthenticationInfo對象,否則拋出AuthenticationException異常。
權限校驗是控制用戶對資源訪問權限的過程。在Shiro中,我們可以通過自定義Realm來實現權限校驗。
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
String username = (String) principals.getPrimaryPrincipal();
User user = userService.findByUsername(username);
SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
authorizationInfo.setRoles(userService.findRoles(username));
authorizationInfo.setStringPermissions(userService.findPermissions(username));
return authorizationInfo;
}
在doGetAuthorizationInfo方法中,我們可以通過PrincipalCollection獲取當前用戶的用戶名,然后查詢該用戶的角色和權限,并將其設置到SimpleAuthorizationInfo對象中。
在Spring Boot項目中,我們可以通過配置類來整合Shiro。
@Configuration
public class ShiroConfig {
@Bean
public ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager) {
ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
shiroFilterFactoryBean.setSecurityManager(securityManager);
// 配置攔截器
Map<String, String> filterChainDefinitionMap = new LinkedHashMap<>();
filterChainDefinitionMap.put("/login", "anon");
filterChainDefinitionMap.put("/logout", "logout");
filterChainDefinitionMap.put("/**", "authc");
shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
// 配置登錄頁面
shiroFilterFactoryBean.setLoginUrl("/login");
// 配置登錄成功后的頁面
shiroFilterFactoryBean.setSuccessUrl("/index");
// 配置未授權頁面
shiroFilterFactoryBean.setUnauthorizedUrl("/403");
return shiroFilterFactoryBean;
}
@Bean
public SecurityManager securityManager(Realm realm) {
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
securityManager.setRealm(realm);
return securityManager;
}
@Bean
public Realm realm() {
return new MyRealm();
}
}
在Shiro中,我們可以通過配置攔截器來控制資源的訪問權限。常見的攔截器有:
- anon:匿名訪問,不需要認證。
- authc:需要認證才能訪問。
- logout:退出登錄。
通過shiroFilterFactoryBean.setLoginUrl()和shiroFilterFactoryBean.setUnauthorizedUrl()方法,我們可以配置登錄頁面和未授權頁面。
在Spring Boot項目中,我們可以通過Controller來實現登錄功能。
@Controller
public class LoginController {
@GetMapping("/login")
public String login() {
return "login";
}
@PostMapping("/login")
public String doLogin(@RequestParam String username, @RequestParam String password, Model model) {
Subject subject = SecurityUtils.getSubject();
UsernamePasswordToken token = new UsernamePasswordToken(username, password);
try {
subject.login(token);
return "redirect:/index";
} catch (AuthenticationException e) {
model.addAttribute("error", "用戶名或密碼錯誤");
return "login";
}
}
}
在doLogin方法中,我們可以通過SecurityUtils.getSubject()獲取當前用戶,然后創建一個UsernamePasswordToken對象,并調用subject.login()方法進行登錄。如果登錄成功,則跳轉到首頁;如果登錄失敗,則返回登錄頁面并顯示錯誤信息。
在Spring Boot項目中,我們可以通過注解來實現權限校驗。
@Controller
public class UserController {
@RequiresRoles("admin")
@GetMapping("/admin")
public String admin() {
return "admin";
}
@RequiresPermissions("user:view")
@GetMapping("/user")
public String user() {
return "user";
}
}
在Shiro配置類中,我們需要啟用注解支持。
@Bean
public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager) {
AuthorizationAttributeSourceAdvisor advisor = new AuthorizationAttributeSourceAdvisor();
advisor.setSecurityManager(securityManager);
return advisor;
}
通過@RequiresRoles和@RequiresPermissions注解,我們可以控制用戶對資源的訪問權限。如果用戶沒有相應的角色或權限,則會被重定向到未授權頁面。
在整合Shiro的過程中,可能會遇到一些常見問題。以下是一些常見問題及其解決方案。
解決方案:檢查Shiro配置類中的攔截器配置,確保攔截器配置正確。
解決方案:檢查自定義Realm中的認證邏輯,確保用戶名和密碼正確。
解決方案:檢查自定義Realm中的授權邏輯,確保用戶擁有相應的角色和權限。
解決方案:檢查Shiro配置類中的注解支持配置,確保注解支持已啟用。
通過本文的介紹,我們了解了如何在Spring Boot項目中整合Shiro,并實現登錄與權限校驗功能。Shiro強大的安全框架,能夠幫助我們輕松實現用戶認證和權限校驗。希望本文能夠幫助你在實際項目中更好地使用Shiro。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。