首頁 >Java >java教程 >Java API 開發中使用 Apache Shiro 進行權限控制

Java API 開發中使用 Apache Shiro 進行權限控制

WBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWB
WBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWB原創
2023-06-17 21:31:40988瀏覽

Java API 開發中使用 Apache Shiro 進行權限控制

隨著網路技術的發展,越來越多的應用程式採用了基於 API 的架構。對於這種架構來說,資料或服務都以 API 的形式暴露給外部系統或應用程式。在這種情況下,使用者權限的控制是非常重要的。本文主要介紹如何使用 Apache Shiro 來管理 Java API 中的權限問題。

Apache Shiro 的概述

Apache Shiro 是 Apache 軟體基金會的開源框架,用於在應用程式中提供安全認證、授權、密碼管理和會話管理等基本功能。 Apache Shiro 是一個簡單、易於使用的安全框架,使得 Java 開發者能夠專注於業務邏輯而不用擔心安全性問題。

Apache Shiro 的主要組成部分包括:

  1. Subject:代表一個與我們的應用程式互動的用戶,可以是人、程式、服務等。每個 Subject 都有一組安全相關的「身分」(principal),這些身分可用於表示使用者的身分。
  2. SecurityManager:用於管理應用程式的安全性操作。其主要職責是進行身份驗證、授權、加密等。
  3. Realm:用於取得應用程式的數據,例如使用者、角色、權限等等。資料可能儲存在資料庫、檔案等等。
  4. SessionManager:針對每個使用者管理其會話訊息,包括建立、失效、維護等。
  5. Session:為每個使用者維護其會話訊息,包括使用者登入狀態等。
  6. Cryptography:提供加密和雜湊演算法等安全服務。

基於上述組成部分,Shiro 提供了一套完整的安全框架,可以用於開發 Java 應用程式中的安全模組。

使用 Apache Shiro 進行權限控制

在開發 Java API 過程中,經常需要對使用者進行權限控制,Shiro 提供了靈活精簡​​的方案來實現該功能。以下介紹具體的實作方法:

  1. 引入 Shiro 依賴套件

#首先需要將 Shiro 的相關依賴套件加入專案。例如,在Maven 專案中,可以在pom.xml 中新增以下程式碼:

<dependency>
    <groupId>org.apache.shiro</groupId>
    <artifactId>shiro-core</artifactId>
    <version>1.5.3</version>
</dependency> 
  1. #定義Realm 類別

在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 等服務層來查詢資料庫中的相關信息,以便取得使用者資料。

  1. 設定 Shiro Filter

在 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 等依賴來注入相關的服務,以實現權限控制和使用者驗證。

  1. 在 Java API 中使用 Shiro 進行權限控制

在完成上述步驟後,我們就可以在 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中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn