返回

Apache Shiro Realm 使用指南,构建安全认证授权应用程序

后端

Apache Shiro Realm 实战

Apache Shiro 是一个流行的 Java 安全框架,它提供了认证、授权、加密和其他安全特性。Realm 是 Shiro 中的核心组件之一,它是 Shiro 用来验证用户身份和管理授权信息的数据源。

在本文中,我们将通过一个简单的示例来演示如何使用 Shiro Realm。我们将创建一个简单的 Java Web 应用程序,并使用 Shiro 来管理用户的认证和授权。

1. 创建 Java Web 应用程序

首先,我们需要创建一个简单的 Java Web 应用程序。您可以使用您喜欢的任何 Java Web 框架,比如 Spring Boot 或 Play Framework。

2. 集成 Shiro

接下来,我们需要在 Java Web 应用程序中集成 Shiro。您可以通过 Maven 或 Gradle 来添加 Shiro 依赖。

<dependency>
    <groupId>org.apache.shiro</groupId>
    <artifactId>shiro-core</artifactId>
    <version>1.7.1</version>
</dependency>

3. 配置 Shiro

在集成 Shiro 之后,我们需要对其进行配置。您可以通过在 Java 代码中或在配置文件中配置 Shiro。

在 Java 代码中配置 Shiro 的示例:

ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
shiroFilterFactoryBean.setLoginUrl("/login");
shiroFilterFactoryBean.setSuccessUrl("/home");
shiroFilterFactoryBean.setUnauthorizedUrl("/403");

Map<String, String> filterChainDefinitionMap = new HashMap<>();
filterChainDefinitionMap.put("/login", "anon");
filterChainDefinitionMap.put("/home", "authc");
filterChainDefinitionMap.put("/**", "authc");

shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);

在配置文件中配置 Shiro 的示例:

shiro.loginUrl = /login
shiro.successUrl = /home
shiro.unauthorizedUrl = /403

shiro.filterChainDefinitionMap.anon = /login
shiro.filterChainDefinitionMap.authc = /home, /**

4. 创建 Realm

接下来,我们需要创建一个 Realm 来管理用户的认证和授权信息。我们可以实现 Shiro 提供的 Realm 接口,也可以使用 Shiro 提供的内置 Realm。

在本文中,我们将创建一个简单的 Realm,它将从内存中加载用户的认证和授权信息。

public class MyRealm implements Realm {

    private Map<String, String> userCredentials = new HashMap<>();
    private Map<String, Set<String>> userRoles = new HashMap<>();

    public MyRealm() {
        // 初始化用户认证和授权信息
        userCredentials.put("admin", "admin");
        userCredentials.put("user", "user");

        userRoles.put("admin", Set.of("admin"));
        userRoles.put("user", Set.of("user"));
    }

    @Override
    public String getName() {
        return "MyRealm";
    }

    @Override
    public boolean supports(AuthenticationToken token) {
        return token instanceof UsernamePasswordToken;
    }

    @Override
    public AuthenticationInfo getAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        String username = (String) token.getPrincipal();
        String password = new String((char[]) token.getCredentials());

        String storedPassword = userCredentials.get(username);
        if (storedPassword == null) {
            throw new UnknownAccountException();
        }

        if (!password.equals(storedPassword)) {
            throw new IncorrectCredentialsException();
        }

        return new SimpleAuthenticationInfo(username, password, getName());
    }

    @Override
    public AuthorizationInfo getAuthorizationInfo(PrincipalCollection principals) {
        String username = (String) principals.getPrimaryPrincipal();
        Set<String> roles = userRoles.get(username);

        return new SimpleAuthorizationInfo(roles);
    }
}

5. 将 Realm 注册到 Shiro

最后,我们需要将 Realm 注册到 Shiro。我们可以通过在 Java 代码中或在配置文件中注册 Realm。

在 Java 代码中注册 Realm 的示例:

SecurityManager securityManager = new DefaultSecurityManager();
securityManager.setRealm(new MyRealm());

SecurityUtils.setSecurityManager(securityManager);

在配置文件中注册 Realm 的示例:

shiro.realm.name = MyRealm

6. 测试 Shiro

现在,我们可以测试 Shiro 是否正常工作。您可以创建一个简单的控制器来测试用户的认证和授权。

@Controller
public class HomeController {

    @RequestMapping("/home")
    public String home() {
        return "home";
    }

    @RequestMapping("/login")
    public String login() {
        return "login";
    }
}

访问 "/home" 路径,您将被重定向到 "/login" 路径。输入用户名和密码后,您将被重定向到 "/home" 路径。

如果您尝试访问 "/admin" 路径,您将被重定向到 "/403" 路径。这是因为您没有 "admin" 角色。

Apache Shiro 认证授权源码解读

在了解了 Apache Shiro Realm 的使用之后,我们再来看看 Shiro 认证授权源码。

Shiro 的认证授权源码位于 org.apache.shiro.authcorg.apache.shiro.authz 包中。

1. 认证

认证过程主要发生在 org.apache.shiro.authc 包中。

AuthenticationToken 接口定义了认证令牌,它包含了用户凭证。

AuthenticationInfo 接口定义了认证信息,它包含了经过认证的用户的信息。

Authenticator 接口定义了认证器,它负责将认证令牌转换成认证信息。

AuthenticationException 是认证过程中可能抛出的异常。

2. 授权

授权过程主要发生在 org.apache.shiro.authz 包中。

AuthorizationInfo 接口定义了授权信息,它包含了经过授权的用户所拥有的权限。

Authorizer 接口定义了授权器,它负责将授权信息与被保护的资源进行匹配。

AuthorizationException 是授权过程中可能抛出的异常。

3. 实例

// 创建认证令牌
UsernamePasswordToken token = new UsernamePasswordToken("admin", "admin");

// 创建认证器
SimpleAuthenticator authenticator = new SimpleAuthenticator();

// 进行认证
AuthenticationInfo authenticationInfo = authenticator.authenticate(token);

// 创建授权器
SimpleAuthorizer authorizer = new SimpleAuthorizer();
authorizer.addRole("admin", "user");
authorizer.addPermission("admin", "create");

// 进行授权
AuthorizationInfo authorizationInfo = authorizer.authorize(authenticationInfo);

// 判断用户是否拥有权限
boolean hasPermission = authorizationInfo.hasRole("admin");

总结

在本文中,我们通过一个简单的示例演示了如何使用 Apache Shiro Realm。我们还对 Shiro 的认证授权源码进行了详细解读。通过本文,您应该对 Apache Shiro Realm 和其认证授权机制有了深入的了解。