Java API 開發中使用 Apache Shiro 進行權限控制
隨著網路技術的發展,越來越多的應用程式採用了基於 API 的架構。對於這種架構來說,資料或服務都以 API 的形式暴露給外部系統或應用程式。在這種情況下,使用者權限的控制是非常重要的。本文主要介紹如何使用 Apache Shiro 來管理 Java API 中的權限問題。
Apache Shiro 的概述
Apache Shiro 是 Apache 軟體基金會的開源框架,用於在應用程式中提供安全認證、授權、密碼管理和會話管理等基本功能。 Apache Shiro 是一個簡單、易於使用的安全框架,使得 Java 開發者能夠專注於業務邏輯而不用擔心安全性問題。
Apache Shiro 的主要組成部分包括:
基於上述組成部分,Shiro 提供了一套完整的安全框架,可以用於開發 Java 應用程式中的安全模組。
使用 Apache Shiro 進行權限控制
在開發 Java API 過程中,經常需要對使用者進行權限控制,Shiro 提供了靈活精簡的方案來實現該功能。以下介紹具體的實作方法:
#首先需要將 Shiro 的相關依賴套件加入專案。例如,在Maven 專案中,可以在pom.xml 中新增以下程式碼:
<dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-core</artifactId> <version>1.5.3</version> </dependency>
在Shiro 中,Realm 負責定義使用者、角色和權限等相關數據,並將其與Shiro 框架整合。因此,定義 Realm 類別是進行權限控制的第一步。
我們可以自訂一個Realm 類,來實現從資料庫中獲取使用者相關資訊的功能,如下所示:
public class MyRealm extends AuthorizingRealm { // 根据用户名获取用户即其角色、权限等相关信息 protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) { // 获取当前用户的身份信息 String username = (String) principalCollection.getPrimaryPrincipal(); // 从数据库中查询用户及其角色 User user = userService.loadByUsername(username); List<Role> roles = roleService.getRolesByUsername(username); // 添加角色 List<String> roleNames = new ArrayList<>(); for (Role role : roles) { roleNames.add(role.getName()); } SimpleAuthorizationInfo info = new SimpleAuthorizationInfo(); info.addRoles(roleNames); // 添加权限 List<String> permissionNames = new ArrayList<>(); for (Role role : roles) { List<Permission> permissions = permissionService.getPermissionsByRoleId(role.getId()); for (Permission permission : permissions) { permissionNames.add(permission.getName()); } } info.addStringPermissions(permissionNames); return info; } // 根据用户名和密码验证用户 protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException { // 获取用户提交的身份信息 String username = (String) authenticationToken.getPrincipal(); String password = new String((char[]) authenticationToken.getCredentials()); // 根据用户名查询用户 User user = userService.loadByUsername(username); if (user == null) { throw new UnknownAccountException(); } // 验证用户密码 String encodedPassword = hashService.hash(password, user.getSalt()); if (!user.getPassword().equals(encodedPassword)) { throw new IncorrectCredentialsException(); } // 如果验证成功,则返回一个身份信息 SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(username, password, getName()); return info; } }
在上述程式碼中,我們透過實作AuthorizingRealm 抽象類別提供的doGetAuthorizationInfo 方法和doGetAuthenticationInfo 方法來獲取使用者的角色和權限信息,以及驗證使用者的身份。這些方法中都會呼叫 UserService、RoleService、PermissionService 等服務層來查詢資料庫中的相關信息,以便取得使用者資料。
在 Java API 中,我們可以設定 Shiro Filter 對請求進行攔截,實現對使用者權限的控制。 Shiro Filter 是一個 Servlet 過濾器,可用於在 Web 應用中進行權限過濾、會話管理等。
在設定 Shiro Filter 時,我們需要設定 Shiro 的安全管理器、自訂的 Realm 類別、編寫好的登入頁面等等。範例如下所示:
@Configuration public class ShiroConfig { @Bean public ShiroFilterFactoryBean shirFilter(SecurityManager securityManager) { ShiroFilterFactoryBean shiroFilter = new ShiroFilterFactoryBean(); shiroFilter.setSecurityManager(securityManager); // 设置登录URL shiroFilter.setLoginUrl("/login"); // 设置无权访问的URL shiroFilter.setUnauthorizedUrl("/unauthorized"); // 配置拦截器规则 Map<String,String> filterChainDefinitionMap = new LinkedHashMap<>(); filterChainDefinitionMap.put("/login", "anon"); filterChainDefinitionMap.put("/logout", "logout"); filterChainDefinitionMap.put("/home", "authc"); filterChainDefinitionMap.put("/admin/**", "roles[admin]"); filterChainDefinitionMap.put("/**", "authc"); shiroFilter.setFilterChainDefinitionMap(filterChainDefinitionMap); return shiroFilter; } @Bean public SecurityManager securityManager(MyRealm myRealm) { DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager(); securityManager.setRealm(myRealm); return securityManager; } @Bean public MyRealm myRealm(HashService hashService, UserService userService, RoleService roleService, PermissionService permissionService) { return new MyRealm(userService, roleService, permissionService, hashService); } @Bean public HashService hashService() { return new SimpleHashService(); } }
在上述程式碼中,我們使用 @Configuration 註解定義了一個 ShiroConfig 類,用於配置 Shiro 相關的參數。在這個類別中,我們定義了 shirFilter() 方法、securityManager() 方法以及 myRealm() 方法,用於配置 Shiro 過濾器、安全管理器以及自訂 Realm 類別。在對應的方法中,我們可以透過依賴注入的方式,使用 UserService、RoleService、PermissionService、HashService 等依賴來注入相關的服務,以實現權限控制和使用者驗證。
在完成上述步驟後,我們就可以在 Java API 中使用 Shiro 進行權限控制了。在具體實作時,我們可以使用 Shiro 提供的 Subject 類別來表示目前使用者。我們可以透過該類別的 hasRole()、isPermitted() 等方法來檢查使用者是否擁有某個角色或權限。以下是一個例子:
@Controller public class ApiController { @RequestMapping("/api/test") @ResponseBody public String test() { Subject currentUser = SecurityUtils.getSubject(); if (currentUser.hasRole("admin")) { return "Hello, admin!"; } else if (currentUser.isAuthenticated()) { return "Hello, user!"; } else { return "Please login first!"; } } }
在上述程式碼中,我們定義了一個 ApiController 類,並在其中定義了一個 test() 方法。在這個方法中,我們首先取得目前使用者 Subject 對象,然後透過呼叫 hasRole()、isPermitted() 等方法來進行權限判斷。
總結
Java API 開發中,權限控制是一個非常重要的問題。 Apache Shiro 提供了一套方便易用的安全框架,可協助 Java 開發者快速實現使用者認證、授權、密碼管理和會話管理等功能。透過本文的介紹,希望讀者能清楚了解如何在 Java API 開發中使用 Shiro 來實現權限控制的功能。
以上是Java API 開發中使用 Apache Shiro 進行權限控制的詳細內容。更多資訊請關注PHP中文網其他相關文章!