详解spring整合shiro权限管理与数据库设计

yizhihongxing

详解Spring整合Shiro权限管理与数据库设计

引言

本文详细讲解如何使用Spring框架整合Shiro权限管理,并给出完整的数据库设计方案和示例代码。

Shiro简介

Shiro是一个强大的Java安全框架,可以提供身份认证、授权、加密等各种安全相关的功能。Shiro使用非常简单,易于集成到Java应用中。

Spring整合Shiro权限管理

引入Shiro依赖

在pom.xml文件中加入以下依赖:

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

配置Shiro

在Spring配置文件中加入以下内容:

<!-- Shiro过滤器 -->
<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
    <property name="securityManager" ref="securityManager"/>
    <property name="loginUrl" value="/login.jsp"/>
    <property name="unauthorizedUrl" value="/unauthorized.jsp"/>
    <property name="filterChainDefinitions">
        <value>
            /login.jsp = anon
            /doLogin = anon
            /logout = logout
            /** = authc
        </value>
    </property>
</bean>

<!-- Shiro安全管理器 -->
<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
    <property name="realm" ref="myRealm"/>
</bean>

<!-- Shiro Realm -->
<bean id="myRealm" class="com.example.MyRealm">
    <!-- 可以配置一些Realm的属性 -->
</bean>

其中,ShiroFilterFactoryBean是Shiro的核心过滤器,必须配置。securityManager是Shiro的安全管理器,使用DefaultWebSecurityManager即可。MyRealm是我们自己实现的认证和授权逻辑,需要用到时自行编写。

编写MyRealm

public class MyRealm extends AuthorizingRealm {

    public void setName(String name) {
        super.setName("myRealm");
    }

    /**
     * 认证逻辑
     */
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        String username = (String) token.getPrincipal();

        // 根据用户名查询用户信息
        User user = userDao.findByUsername(username);

        if (user == null) {
            throw new UnknownAccountException("用户不存在!");
        }

        // 封装认证信息
        SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(user.getUsername(), user.getPassword(), getName());

        return info;
    }

    /**
     * 授权逻辑
     */
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        String username = (String) principals.getPrimaryPrincipal();
        Set<String> roles = userDao.findRoles(username);
        Set<String> permissions = userDao.findPermissions(username);

        // 封装授权信息
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        info.setRoles(roles);
        info.setStringPermissions(permissions);

        return info;
    }
}

其中,doGetAuthenticationInfo方法实现认证逻辑,doGetAuthorizationInfo方法实现授权逻辑。通过调用userDao的方法查询数据库获取用户信息和权限信息。

编写UserDao接口

public interface UserDao {

    User findByUsername(String username);

    Set<String> findRoles(String username);

    Set<String> findPermissions(String username);
}

这是一个比较简单的DAO接口,用于查询用户信息、角色信息和权限信息。实现可以使用MyBatis、Hibernate等持久层框架。

数据库设计

在使用Shiro进行权限管理时,需要设计数据库表来存储用户信息、角色信息和权限信息。

以MySQL为例,以下是一个简单的数据库设计。

用户表

CREATE TABLE `user` (
    `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键',
    `username` varchar(50) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '用户名',
    `password` varchar(50) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '密码',
    `salt` varchar(50) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '' COMMENT '盐值',
    `locked` tinyint(1) NOT NULL DEFAULT '0' COMMENT '0未锁定,1锁定',
    `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
    `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
    PRIMARY KEY (`id`),
    UNIQUE KEY `username` (`username`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='用户表';

角色表

CREATE TABLE `role` (
    `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键',
    `name` varchar(50) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '角色名',
    `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
    `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
    PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='角色表';

用户角色关联表

CREATE TABLE `user_role` (
    `user_id` bigint(20) NOT NULL COMMENT '用户id',
    `role_id` bigint(20) NOT NULL COMMENT '角色id',
    PRIMARY KEY (`user_id`,`role_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='用户角色关联表';

权限表

CREATE TABLE `permission` (
    `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键',
    `name` varchar(50) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '权限名',
    `url` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT 'URL',
    `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
    `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
    PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='权限表';

角色权限关联表

CREATE TABLE `role_permission` (
    `role_id` bigint(20) NOT NULL COMMENT '角色id',
    `permission_id` bigint(20) NOT NULL COMMENT '权限id',
    PRIMARY KEY (`role_id`,`permission_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='角色权限关联表';

示例

以下是一个简单的示例,演示如何使用Shiro进行身份认证和授权。

登录Controller

@Controller
public class LoginController {

    @RequestMapping("/doLogin")
    public String doLogin(String username, String password) {
        // 封装用户名和密码为Token
        UsernamePasswordToken token = new UsernamePasswordToken(username, password);

        try {
            // 进行登录认证
            SecurityUtils.getSubject().login(token);

            return "redirect:/index.jsp";
        } catch (Exception e) {
            e.printStackTrace();
            return "redirect:/login.jsp";
        }
    }
}

权限控制

@Controller
public class UserController {

    @RequiresPermissions("user:view")
    @RequestMapping("/list")
    public String list() {
        // 查询用户列表
        List<User> userList = userService.findAll();

        return "user/list";
    }

    @RequiresPermissions("user:add")
    @RequestMapping("/add")
    public String add(User user) {
        // 添加用户

        return "redirect:/list";
    }

    @RequiresPermissions("user:delete")
    @RequestMapping("/delete")
    public String delete(Long userId) {
        // 删除用户

        return "redirect:/list";
    }
}

在UserController中,使用@RequiresPermissions注解指定方法需要的权限。如果当前用户没有该权限,将会抛出UnauthorizedException异常,需要在异常处理器中进行处理。

结语

本文详细讲解了如何使用Spring框架整合Shiro权限管理,并给出了完整的数据库设计方案和示例代码。Shiro是一个非常好用的Java安全框架,可以帮助我们实现身份认证、授权等各种安全相关的功能。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:详解spring整合shiro权限管理与数据库设计 - Python技术站

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

相关文章

  • Spring Boot 捕捉全局异常 统一返回值的问题

    Spring Boot是一个快速构建Spring应用程序的框架,可以快速实现RESTful API的开发。在开发过程中,我们难免会遇到异常,如数据库连接异常、空指针异常等。如果不处理这些异常,可能会导致应用程序挂掉,或出现不可预期的结果。而且在开发中,我们也需要统一的返回值格式,这样可以提高开发效率。 因此,本文将详细讲解如何通过Spring Boot捕捉全…

    Java 2023年5月27日
    00
  • Java中的字节流和字符流有什么区别?

    在Java标准库中,字节流和字符流是两个很重要的概念。字节流和字符流的区别在于流的传输基本对象不同。字节流主要处理byte类型的数据;而字符流主要处理字符型数据,即16位Unicode字符。 字节流的主要基类是InputStream和OutputStream,字符流的主要基类是Reader和Writer。下面我们详细介绍Java中的字节流和字符流的区别: 字…

    Java 2023年4月27日
    00
  • 浅谈springfox-swagger原理解析与使用过程中遇到的坑

    浅谈springfox-swagger原理解析与使用过程中遇到的坑 1. 什么是springfox-swagger springfox-swagger是一个用于生成API文档的Java库,它可以自动化生成API文档,并提供了一个UI界面,方便用户查看和测试API接口。它基于Swagger规范,可以与Spring框架无缝集成,支持Spring MVC、Spri…

    Java 2023年5月18日
    00
  • 如何通过一张图搞懂springBoot自动注入原理

    下面是关于“如何通过一张图搞懂springBoot自动注入原理”的完整攻略。 1. 简介 在 Spring Boot 中,我们可以使用自动配置完成很多操作,其中最重要的一个就是通过自动注入来维护 Spring 应用程序之间的依赖关系。 Spring Boot 中自动注入的原理比较复杂,但我们可以用一张图来概述它的过程。 2. 图片介绍 下面这张图片展示了自动…

    Java 2023年5月15日
    00
  • Java欧拉函数的计算代码详解

    首先介绍下欧拉函数的定义: 欧拉函数,又称为“φ函数”,表示小于等于n的正整数中有多少个与n互质。记做φ(n)。 Java中计算欧拉函数的代码如下(假设要计算的数为n): public static int eulerFunction(int n) { int res = n; for (int i = 2; i * i <= n; i++) { if…

    Java 2023年5月26日
    00
  • Java中instanceof关键字的用法总结

    下面是Java中instanceof关键字的用法总结。 Java中instanceof关键字的用法总结 1. 什么是instanceof? instanceof是Java中的一个二元运算符,用于判断一个对象是否为一个类的实例,或者是该类的子类或者接口的实例。它的语法如下: result = object instanceof Class 其中,object是…

    Java 2023年5月26日
    00
  • 使用Eclipse配置android开发环境教程

    使用Eclipse配置Android开发环境是一个比较基础的操作,本文将为大家提供一套完整的攻略,方便大家快速地开始Android开发。 步骤1:安装Java环境 在开始Android开发之前,需要先安装Java开发环境。具体可以按照以下步骤进行操作: 下载适合自己系统的JDK,推荐使用Oracle官网下载,网址为:https://www.oracle.co…

    Java 2023年6月15日
    00
  • java web实现自动登录

    让我来简单介绍一下 “java web实现自动登录” 的实现方案。 1. 存储登录状态 在用户登录时,可以将该用户的相关登录信息存储到浏览器的 cookie 中,使得用户在下一次访问时无需重新登录,即可直接登录进入系统,这就是所谓的“自动登录”。 1.1 操作流程 1.用户登陆,输入用户名和密码。 2.后台服务器验证用户信息。若验证成功,则生成token(包…

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