Spring Boot Shiro用户认证

糖果女孩 2024-03-10 ⋅ 17 阅读

介绍

在Web应用程序中,用户认证是一个非常重要的功能。Spring Boot提供了与Shiro集成的便捷方式,以便快速实现安全的用户认证。Shiro是一个功能强大且灵活的开源安全框架,它提供了认证、授权、加密和会话管理等功能。

本文将介绍如何使用Spring Boot和Shiro来实现用户认证的功能,并且通过演示具体的代码示例来帮助读者更好地理解。

环境配置

在开始之前,确保你已经安装并配置好了以下环境:

  • Java开发环境
  • Maven构建工具
  • Spring Boot

添加依赖

首先,在你的Maven项目的pom.xml文件中,添加以下依赖:

<dependencies>
    <!-- Spring Boot Starter -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

    <!-- Shiro Starter -->
    <dependency>
        <groupId>org.apache.shiro</groupId>
        <artifactId>shiro-spring-boot-starter</artifactId>
        <version>1.7.1</version>
    </dependency>
</dependencies>

这样,你的项目就添加了Spring Boot和Shiro的相关依赖。

配置Shiro

接下来,你需要创建一个Shiro配置类来配置Shiro的相关信息。在src/main/java目录下创建一个新的Java类,命名为ShiroConfig

@Configuration
public class ShiroConfig {
    @Bean
    public ShiroFilterFactoryBean shiroFilterFactoryBean(DefaultWebSecurityManager securityManager) {
        ShiroFilterFactoryBean factoryBean = new ShiroFilterFactoryBean();
        factoryBean.setSecurityManager(securityManager);
        factoryBean.setLoginUrl("/login");
        factoryBean.setUnauthorizedUrl("/403");

        // 设置过滤器链
        Map<String, String> filterChainDefinitionMap = new LinkedHashMap<>();
        filterChainDefinitionMap.put("/login", "anon");
        filterChainDefinitionMap.put("/logout", "logout");
        filterChainDefinitionMap.put("/**", "authc");

        factoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);

        return factoryBean;
    }

    @Bean
    public DefaultWebSecurityManager securityManager(Realm realm) {
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        securityManager.setRealm(realm);
        return securityManager;
    }

    @Bean
    public Realm realm() {
        return new MyRealm();
    }
}

这个配置类使用@Configuration注解告诉Spring Boot,这是一个配置类。其中,shiroFilterFactoryBean方法用于配置Shiro的过滤器链,securityManager方法用于创建Shiro的安全管理器,realm方法用于创建自定义的Realm。

实现自定义的Realm

在上面的配置类中,我们使用了自定义的Realm,这是为了定义Shiro的认证逻辑。在src/main/java目录下创建一个新的Java类,命名为MyRealm

public class MyRealm extends AuthorizingRealm {
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
        // 设置用户的角色和权限
        authorizationInfo.addRole("admin");
        authorizationInfo.addStringPermission("user:create");
        authorizationInfo.addStringPermission("user:delete");
        return authorizationInfo;
    }

    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        String username = (String) token.getPrincipal();

        // 模拟从数据库中获取用户信息
        if (!"admin".equals(username)) {
            throw new UnknownAccountException();
        }

        // 返回认证信息
        return new SimpleAuthenticationInfo(username, "password", getName());
    }
}

在这个自定义的Realm中,我们通过重写doGetAuthorizationInfo方法和doGetAuthenticationInfo方法来定义Shiro的授权和认证逻辑。

doGetAuthorizationInfo方法中,我们设置了用户的角色和权限。具体的角色和权限信息应该从数据库中获取,这里我们仅作演示之用。

doGetAuthenticationInfo方法中,我们模拟从数据库中获取用户信息,并返回认证信息。

创建登录页面

创建一个新的HTML文件,名为login.html,在src/main/resources/static/目录下。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Login</title>
</head>
<body>
    <h1>Login</h1>
    <form action="/login" method="post">
        <label for="username">Username:</label>
        <input type="text" id="username" name="username">
        <br>
        <label for="password">Password:</label>
        <input type="password" id="password" name="password">
        <br>
        <input type="submit" value="Login">
    </form>
</body>
</html>

这个登录页面包含了一个表单,用于用户输入用户名和密码。提交表单后,页面会将表单数据发送到/login接口。

创建登录成功页面

创建一个新的HTML文件,名为success.html,在src/main/resources/static/目录下。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Success</title>
</head>
<body>
    <h1>Login Successful!</h1>
</body>
</html>

这个页面显示了登录成功的消息。

创建登录失败页面

创建一个新的HTML文件,名为failure.html,在src/main/resources/static/目录下。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Failure</title>
</head>
<body>
    <h1>Login Failure!</h1>
</body>
</html>

这个页面显示了登录失败的消息。

编写控制器

创建一个新的Java类,命名为LoginController,在src/main/java目录下。

@Controller
public class LoginController {
    @GetMapping("/login")
    public String login() {
        return "login";
    }

    @PostMapping("/login")
    public String doLogin(String username, String password, HttpServletRequest request) {
        UsernamePasswordToken token = new UsernamePasswordToken(username, password);
        Subject currentUser = SecurityUtils.getSubject();
        try {
            currentUser.login(token);
            return "redirect:/success";
        } catch (UnknownAccountException e) {
            return "redirect:/failure";
        }
    }

    @GetMapping("/success")
    public String success() {
        return "success";
    }

    @GetMapping("/failure")
    public String failure() {
        return "failure";
    }
}

在这个控制器中,login方法返回login.html页面,用于展示登录页面。

doLogin方法接收表单数据,并通过SecurityUtils.getSubject().login(token)进行用户认证。如果认证成功,就重定向到success页面;如果认证失败,就重定向到failure页面。

success方法返回success.html页面,用于展示登录成功的消息。

failure方法返回failure.html页面,用于展示登录失败的消息。

运行应用程序

现在,你可以运行你的应用程序了。执行以下Maven命令来启动应用程序:

mvn spring-boot:run

然后,在浏览器中访问http://localhost:8080/login,你将看到登录页面。输入用户名和密码进行登录,系统将根据输入的信息进行用户认证。如果认证成功,将重定向到成功页面;否则将重定向到失败页面。

结论

本文介绍了如何使用Spring Boot和Shiro来实现用户认证的功能。通过自定义Realm来定义Shiro的授权和认证逻辑,通过配置类来配置Shiro的相关信息,通过控制器来处理登录请求。

Shiro是一个功能强大且灵活的安全框架,可以帮助我们实现多种安全功能。希望本文能帮助读者更好地理解和使用Spring Boot和Shiro来进行用户认证。

如果你想了解更多关于Spring Boot和Shiro的内容,请查阅官方文档和其他相关资源。

参考链接:


全部评论: 0

    我有话说: