springboot集成shiro权限管理简单实现

下面就为您讲解“SpringBoot集成Shiro权限管理简单实现”的详细攻略。

一、配置

1.1 引入依赖

在Maven或Gradle中引入Shiro和SpringBoot的相关依赖:

Maven:

<dependency>
  <groupId>org.apache.shiro</groupId>
  <artifactId>shiro-web</artifactId>
  <version>1.7.1</version> <!-- 版本可根据实际情况进行调整 -->
</dependency>

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-web</artifactId>
</dependency>

Gradle:

implementation 'org.apache.shiro:shiro-web:1.7.1' // 版本可根据实际情况进行调整
implementation 'org.springframework.boot:spring-boot-starter-web'

1.2 配置Shiro

在SpringBoot中使用Shiro,我们需要在配置类(通常是Application.java)中添加一个ShiroFilterFactoryBean和一个DefaultWebSecurityManager的Bean。

示例代码:

@Configuration
public class Application {

    @Bean
    public ShiroFilterFactoryBean shiroFilterFactoryBean() {
        //创建shiroFilterFactoryBean 实例
        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
        //设置SecurityManager
        shiroFilterFactoryBean.setSecurityManager(securityManager());
        //设置登录页面地址
        shiroFilterFactoryBean.setLoginUrl("/login");
        //设置无权限路径
        shiroFilterFactoryBean.setUnauthorizedUrl("/unauthorized");
        // 拦截器.
        Map<String, String> map = new HashMap<String, String>();
        // 配置不会被拦截的链接 顺序判断
        //anon:所有url都可以匿名访问
        map.put("/login", "anon");
        map.put("/static/**", "anon");  //静态资源不拦截
        map.put("/**", "authc");  //其他链接必须认证后才能访问
        shiroFilterFactoryBean.setFilterChainDefinitionMap(map);

        return shiroFilterFactoryBean;
    }

    @Bean
    public DefaultWebSecurityManager securityManager() {
        //创建securityManager实例
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        //设置realm
        securityManager.setRealm(myShiroRealm());
        return securityManager;
    }

    /**
     * 自定义realm
     */
    @Bean
    public MyShiroRealm myShiroRealm() {
        //创建realm实例
        MyShiroRealm myShiroRealm = new MyShiroRealm();
        return myShiroRealm;
    }
}

1.3 配置Realm

自定义的Realm需要继承org.apache.shiro.realm.AuthorizingRealm类,实现其中的protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals)和protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token)方法,完成授权和身份认证的逻辑。

示例代码:

public class MyShiroRealm extends AuthorizingRealm {

    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        //授权逻辑
        //获取当前用户
        User user = (User) principals.getPrimaryPrincipal();
        //创建授权对象
        SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
        //向授权对象中添加角色和权限
        authorizationInfo.addRoles(user.getRoles());
        authorizationInfo.addStringPermissions(user.getPermissions());
        return authorizationInfo;
    }

    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        //身份认证逻辑
        //获取用户输入的账号和密码
        UsernamePasswordToken usernamePasswordToken = (UsernamePasswordToken) token;
        String username = usernamePasswordToken.getUsername();
        String password = new String(usernamePasswordToken.getPassword());
        //根据用户名查找数据库中的用户对象
        User user = userService.findByUsername(username);
        if (user == null) {
            throw new UnknownAccountException(); //账号不存在
        }
        if (!password.equals(user.getPassword())) {
            throw new IncorrectCredentialsException(); //密码错误
        }
        //创建身份认证对象
        return new SimpleAuthenticationInfo(user, password, getName());
    }
}

二、使用

2.1 创建用户实体类

public class User implements Serializable {

    private Integer id;
    private String username;
    private String password;
    private List<String> roles;
    private List<String> permissions;

    //省略getter和setter方法
}

2.2 设计登录页面

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>登录</title>
</head>
<body>
    <h1>登录</h1>
    <form action="/login" method="post">
        <p>用户名: <input type="text" name="username"></p>
        <p>密码: <input type="password" name="password"></p>
        <p><input type="submit" value="登录"></p>
    </form>
</body>
</html>

2.3 创建根据用户名查询用户的服务接口和实现类

public interface UserService {
    User findByUsername(String username);
}

@Service
public class UserServiceImpl implements UserService {

    @Override
    public User findByUsername(String username) {
        //模拟从数据库中查询用户
        if ("admin".equals(username)) {
            User user = new User();
            user.setUsername("admin");
            user.setPassword("123456");
            user.setRoles(Arrays.asList("admin"));
            user.setPermissions(Arrays.asList("user:select", "user:update", "user:delete"));
            return user;
        } else {
            return null;
        }
    }
}

2.4 编写授权和鉴权代码

在Controller中编写授权和鉴权代码,实现对鉴权失败的情况进行处理。

@RestController
public class UserController {

    @RequestMapping("/user/select")
    public String selectUser() {
        return "查询用户成功";
    }

    @RequestMapping("/user/update")
    public String updateUser() {
        return "更新用户信息成功";
    }

    @RequestMapping("/user/delete")
    public String deleteUser() {
        return "删除用户成功";
    }

    @RequestMapping("/unauthorized")
    public String unauthorized() {
        return "没有权限访问此页面";
    }
}

2.5 测试

完成上述步骤后,运行程序并访问localhost:8080/login,输入admin/123456登录后,访问/user/select、/user/update、/user/delete,应该能正常访问,否则将会跳转到unauthorized页面。

三、总结

至此,我们已经完成了SpringBoot集成Shiro权限管理的简单实现。在使用过程中需要注意:

  • 在自定义的Realm中返回的SimpleAuthenticationInfo对象中,第一个参数必须是用户对象。
  • 自定义的Realm必须添加到SecurityManager中。
  • 可以通过编写自定义的Filter实现更多的权限控制。
  • 若需要对部分用户进行特殊处理,可以重新实现AuthorizingRealm的授权方法。
  • 完整示例代码请参考GitHub上的开源项目。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:springboot集成shiro权限管理简单实现 - Python技术站

(0)
上一篇 2023年5月20日
下一篇 2023年5月20日

相关文章

  • Spring MVC—数据绑定和表单标签详解

    SpringMVC 数据绑定和表单标签详解 SpringMVC是一个非常流行的Java Web框架。它通过模型-视图-控制器(MVC)架构,实现了对Web应用程序的易于扩展和维护的分层设计。在实际开发中,数据绑定和表单标签是SpringMVC中最重要的两个特性之一。 数据绑定 数据绑定指的是将请求参数(如表单提交的数据)自动绑定到JavaBean对象上。Sp…

    Java 2023年6月15日
    00
  • Java实现AES加密算法的简单示例分享

    那么我将详细讲解“Java实现AES加密算法的简单示例分享”的完整攻略,包括实现步骤,示例说明等。 第一步:引入依赖 Java实现AES加密算法需要引入如下两个依赖: <dependency> <groupId>javax.crypto</groupId> <artifactId>javax.crypto-ap…

    Java 2023年5月26日
    00
  • java实现登录窗口

    下面就是Java实现登录窗口的攻略: 1. 准备工作 在Java中实现登录窗口,首先要准备以下几项工作: Java开发环境,如JDK或者集成开发环境(IDE); Swing类库,它是Java中的图形用户界面(GUI)工具包,用于构建界面组件; 了解Java的事件机制,因为登录窗口需要监听用户的操作。 2. 创建登录窗口 要创建一个登录窗口,需要用到Java中…

    Java 2023年5月19日
    00
  • Spring Security 实现短信验证码登录功能

    下面将为您详细讲解“Spring Security 实现短信验证码登录功能”的完整攻略。 1. 准备工作 添加Spring Security和Spring MVC依赖; 引入相关的Jackson依赖,可用于将Java对象序列化为json格式; 配置Spring Security,开启HttpSecurity和authenticationManagerBean…

    Java 2023年5月20日
    00
  • Jackson序列化丢失泛型的解决

    在Java中,使用Jackson库进行序列化和反序列化是非常常见的。然而,当我们使用泛型时,Jackson序列化可能会丢失泛型信息,导致反序列化时出现问题。在本文中,我们将详细讲解如何解决Jackson序列化丢失泛型的问题,并提供两个示例来说明如何使用这些方法。 问题描述 当我们使用泛型时,Jackson序列化可能会丢失泛型信息。例如,考虑以下示例: pub…

    Java 2023年5月18日
    00
  • 使用Criteria进行分组求和、排序、模糊查询的实例

    下面我将为你详细讲解使用Criteria进行分组求和、排序、模糊查询的完整攻略。 一、Criteria的概述 Hibernate 中的 Criteria 查询是为了解决 HQL 表达式中所没有解决的灵活的高级查询,也可以免去写 SQL 的烦恼,使用标准的方式,所有的查询条件都封装成一个对象。 Criteria 对象可以通过 Restrictions 的静态方…

    Java 2023年5月20日
    00
  • Maven分模块开发执行指令失败的问题

    Maven分模块开发是一种常见的软件开发方法,但在进行模块执行指令时,有时会遇到执行失败的问题。本攻略旨在帮助开发人员解决Maven分模块开发执行指令失败的问题,步骤如下: 一、检查pom.xml文件配置 在进行Maven分模块开发时,每个子模块都有自己的pom.xml文件。执行指令失败时,首先需要检查各个子模块的pom.xml文件是否正确配置。特别要注意以…

    Java 2023年5月19日
    00
  • Java中Singleton的3种实现方式详解

    Java中Singleton的3种实现方式详解 一、什么是Singleton? 在面向对象编程中,Singleton(单例)是一种创建模式,用于确保一个类只有一个实例,并提供了一个全局访问点。 在程序中,单例模式通常用于管理共享资源,例如数据库连接池、日志输出、配置信息等。 二、Singleton的实现方式 1. 饿汉式(Eager Initializati…

    Java 2023年5月18日
    00
合作推广
合作推广
分享本页
返回顶部