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

详解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日

相关文章

  • YII2.0框架行为(Behavior)深入详解

    下面针对”YII2.0框架行为(Behavior)深入详解”进行详细讲解,并且提供两个示例说明。 什么是行为(Behavior) 行为是 Yii 2 中一个非常重要的概念,它常常被用来实现代码复用及属性的自定义处理。通俗点来说,行为可以看作是一种类的特殊封装。在 Yii 2 中,每个行为可以封装一个函数或者一组函数。 行为的分类 可以把行为分为两种:普通行为…

    Java 2023年6月15日
    00
  • JPA配置详解之jpaProperties用法

    JPA配置详解之jpaProperties用法 为了更好地管理JPA配置,Spring Boot提供了许多配置属性,其中一个是jpaProperties属性。在这篇攻略中,我们将学习如何在Spring Boot应用程序中使用jpaProperties属性,并且将通过示例代码演示其用法。 使用示例 假设我们有一个简单的Spring Boot应用程序,并且需要使…

    Java 2023年5月20日
    00
  • mysql 海量数据的存储和访问解决方案

    MySQL 是一种流行的关系型数据库,通常被用于存储和管理各种规模大小的数据。针对海量数据的存储和访问问题,有以下几种解决方案: 1. 数据分区 概述 数据分区是指把数据库表中的数据分散到不同的存储设备上,以提高对大量数据的查询和处理性能。MySQL 支持两种分区方式:根据范围分区和根据哈希值分区。根据范围分区是指把表的每个分区按照指定的范围划分,而根据哈希…

    Java 2023年6月16日
    00
  • Java多线程提交按照时间顺序获取线程结果详解流程

    Java多线程提交按照时间顺序获取线程结果,是一种常见的并发处理方式。其流程大致可以分为任务提交、线程池处理、结果收集三个过程。 任务提交 在Java中,可以通过Executors提供的静态方法创建线程池,以便统一管理和复用线程资源,同时避免频繁创建线程的性能开销。 ExecutorService executor = Executors.newFixedT…

    Java 2023年5月19日
    00
  • VScode+Java配置与使用的详细步骤

    下面我将为您讲解“VScode+Java配置与使用的详细步骤”,主要包括以下几个步骤: 安装JDK并添加环境变量 安装VScode及必要的插件 创建Java项目并编辑代码 调试Java代码 接下来,我将一步步为您详细介绍。 1. 安装JDK并添加环境变量 Java需要使用JDK才能进行开发,因此我们首先需要安装Java Development Kit(JDK…

    Java 2023年5月26日
    00
  • spring整合JMS实现同步收发消息(基于ActiveMQ的实现)

    下面我将给您详细讲解“spring整合JMS实现同步收发消息(基于ActiveMQ的实现)”的完整攻略。 什么是JMS JMS(Java Messaging Service)是Java EE标准的消息中间件API。它提供了一种发送和接收消息的标准方法,以及处理和管理消息的机制。 什么是ActiveMQ ActiveMQ是一款常用的基于JMS的开源消息中间件,…

    Java 2023年5月20日
    00
  • jsp 对request.getSession(false)的理解(附程序员常疏忽的一个漏洞)

    首先,让我们来理解一下 JSP 对 request.getSession(false) 方法的理解以及可能存在的漏洞。 在 JSP 中,每个请求都会有一个 HttpServletRequest 对象,我们可以利用它来获取 Session 对象。通常,我们使用 request.getSession() 来获取 Session 对象,如果 Session 对象不…

    Java 2023年6月15日
    00
  • 深入了解SpringBoot中@ControllerAdvice的介绍及三种用法

    我们来详细讲解“深入了解SpringBoot中@ControllerAdvice的介绍及三种用法”的完整攻略。 介绍 @ControllerAdvice是Spring MVC提供的一个用于全局异常处理、数据绑定等工作的注解。使用@ControllerAdvice不仅能够处理所有控制器中抛出的异常,还能实现一些额外的公共处理逻辑,比如记录日志,返回统一格式的错…

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