Spring Boot Security 实现后台&权限管理系统(一)

废话连篇

Hi!各位博客大佬们,初来乍到,本人是工龄仅有一年半载的初级程序员(俗称:菜鸟),说来惭愧,距今接触Java开发已有了近两年之久,可时间越往后挪我就越发感到惶恐不安,很多次甚至反思自己到底是不是能够从事该行业,几经辗转发现了自身一个问题,就是无论做什么都只在脑子里过一遍,却从不做任何笔记、流程图等。所以,从这里开始,就通过博客的方式记录下自己的一言一行,一是为了提升自己,二是为了供后来的初学者所参考,避免踩坑!由于自身能力有限,该博客如有任何问题,还请大佬们多多包涵及指正!

1、Spring Boot Security


如图,是一种通用的用户权限模型。一般情况下会有5张表,分别是:用户表,角色表,权限表,用户角色关系表,角色权限对应表。
一般,资源分配时是基于角色的(即,资源访问权限赋给角色,用户通过角色进而拥有权限);而访问资源的时候是基于资源权限去进行授权判断的。
Spring Security和Apache Shiro是两个应用比较多的权限管理框架。Spring Security依赖Spring,其功能强大,相对于Shiro而言学习难度稍大一些。
Spring的强大是不言而喻的,可扩展性也很强,强大到用Spring家族的产品只要按照其推荐的做法来就非常非常简单,否则,自己去整合过程可能会很痛苦。
目前,我们项目是基于Spring Boot的,而且Spring Boot的权限管理也是推荐使用Spring Security的,所以再难也是要学习的。

1.1、Spring Security 简介

Spring Security致力于为Java应用提供认证和授权管理。它是一个强大的,高度自定义的认证和访问控制框架。
具体介绍参见 https://docs.spring.io/spring-security/site/docs/5.0.5.RELEASE/reference/htmlsingle/
这句话包括两个关键词:Authentication(认证)和 Authorization(授权,也叫访问控制)
认证是验证用户身份的合法性,而授权是控制你可以做什么。
简单地来说,认证就是你是谁,授权就是你可以做什么。

1.2、Spring Security接口介绍

  • AuthenticationManager

    在这里不过多讲述,有兴趣的小伙伴可以看看AuthenticationManager原理

  • AuthenticationProvider

    AuthenticationProvider接口是用于认证的,可以通过实现这个接口来定制我们自己的认证逻辑,它的实现类有很多,默认的是JaasAuthenticationProvider,它的全称是Java Authentication and Authorization Service (JAAS),常用的是AbstractUserDetailsAuthenticationProvider以及它的子类DaoAuthenticationProvider。

  • AccessDecisionManager

    AccessDecisionManager做处最终的访问控制决策,故名思义,它决定了用户是否可以访问某个资源,因此,我们可以实现AccessDecisionManager用于定制我们自己的授权逻辑。

  • AccessDecisionVoter

    AccessDecisionVoter投票器,在授权时通过投票的方式决定用户是否具有权限,这里涉及到了三种投票规则,AffirmativeBased如果有一票通过,则视为有权访问,ConsensusBased多数表决(少从多),如果有多数表决通过,则有权访问,反之无权访问。UnanimousBased如果有一票投了否决,则直接视为无权访问。

  • UserDetailsService

    UserDetailsService用户详细信息服务接口,该接口中只存在一个方法loadUserByUsername() 该方法通过指定的用户名用来获取UserDetails,通常在Security应用中,我们会自定义一个接口用来实现它,并与之与数据库进行交互。

集成Spring Security

接下来的方式,我们都按照官方文档的方式来进行配置,即我们需要在配置文件中添加UserDetailsService, AuthenticationProvider, or AuthenticationManager这几种类型的Bean。
这里我使用到了SpringBoot多模块,主要目的是多模块的划分可以降低代码之间的耦合性(从类级别的耦合提升到jar包级别的耦合),每个模块都可以是自解释的(通过模块名或者模块文档),模块还规范了代码边界的划分。

SpringBoot多模块构建

我们按照SpringBoot多模块构建完毕后,我的项目结构如下:

模块 说明
bpms-permission-api 项目接口服务层,包涵Java实体、数据交互接口(dao)及服务接口(service)
bpms-permission-common 公共服务层,主要包涵一些工具类、常量、过滤器、拦截器等
bpms-permission-management 权限层,和权限有关的都在这里面。
bpms-permission-service 项目接口服务实现层,mybatis的XML文件以及接口实现
bpms-permission-web 项目视图控制层,包含前端部分和控制器

构建完成之后,删除多余文件,确保除了bpms-permission-web模块,其余模块的结构如下图所示:

maven依赖

多模块在引入maven时需要注意,尽量把所有的maven依赖都放置在父pom文件下,其他模块需要用的依赖再引用即可。

  • 父级模块(bpms2.0)maven配置如下:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.2.0.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.zlx</groupId>
    <artifactId>bpms2.0</artifactId>
    <version>1.0.1-SNAPSHOT</version>
    <name>bpms</name>
    <!--父级项目的packaging设置为pom-->
    <packaging>pom</packaging>
    <description>SpringBoot父工程</description>
    <!--主工程包含子模块工厂配置-->
    <modules>
        <module>bpms</module>
    </modules>
    <!--配置参数-->
    <properties>
        <java.version>1.8</java.version>
        <json.version>1.2.56</json.version>
        <mybatis-plus-boot-starter.version>3.2.0</mybatis-plus-boot-starter.version>
        <lombok.version>1.18.8</lombok.version>
        <commons-collection.version>3.2.2</commons-collection.version>
        <commons-lang3.version>3.8.1</commons-lang3.version>
        <jwt.version>0.9.1</jwt.version>
        <oauth-auto.version>2.0.6.RELEASE</oauth-auto.version>
        <thymeleaf-extras-data-attribute.version>3.0.4.RELEASE</thymeleaf-extras-data-attribute.version>
        <oauth2.version>2.3.6.RELEASE</oauth2.version>
        <springsecurity-jwt.version>1.0.7.RELEASE</springsecurity-jwt.version>
        <common-cite.version>1.0.1-SNAPSHOT</common-cite.version>
        <spring.boot.version>2.2.0.RELEASE</spring.boot.version>
        <mysql.version>8.0.18</mysql.version>
        <jedis.version>2.9.0</jedis.version>
        <poi.version>4.1.0</poi.version>
        <pdf.version>5.5.13</pdf.version>
        <org.json.version>20180813</org.json.version>
        <activiti.version>5.22.0</activiti.version>
        <spring.social.version>1.1.6.RELEASE</spring.social.version>
    </properties>


    <!--子模块Spring Boot公共依赖-->
    <dependencies>
        <!--        springboot相关  begin-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
            <version>${spring.boot.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <version>${spring.boot.version}</version>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
            <version>${spring.boot.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <version>${spring.boot.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
            <version>${spring.boot.version}</version>
            <exclusions>
                <exclusion>
                    <groupId>io.lettuce</groupId>
                    <artifactId>lettuce-core</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>redis.clients</groupId>
                    <artifactId>jedis</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
            <version>${spring.boot.version}</version>
        </dependency>
        <!--        springboot相关  end-->
        <!--        redis start-->
        <dependency>
            <groupId>redis.clients</groupId>
            <artifactId>jedis</artifactId>
            <version>3.1.0</version>
        </dependency>
        <!--        redis end-->
        <!-- mysql驱动  start-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
            <version>${mysql.version}</version>
        </dependency>
        <!-- mysql驱动  end-->
        <!--mybatis-plus begin-->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>${mybatis-plus-boot-starter.version}</version>
        </dependency>
        <!--mybatis-plus end-->
        <!--spring-security-oauth2 begin-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
            <version>${spring.boot.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.security.oauth.boot</groupId>
            <artifactId>spring-security-oauth2-autoconfigure</artifactId>
            <version>${oauth-auto.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.security.oauth</groupId>
            <artifactId>spring-security-oauth2</artifactId>
            <version>${oauth2.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-jwt</artifactId>
            <version>${springsecurity-jwt.version}</version>
        </dependency>
        <!--spring-security-oauth2 end-->
        <!--        模板引擎支持SpringSecurity  start-->
        <dependency>
            <groupId>org.thymeleaf.extras</groupId>
            <artifactId>thymeleaf-extras-springsecurity5</artifactId>
            <version>${thymeleaf-extras-data-attribute.version}</version>
        </dependency>
        <!--        模板引擎支持SpringSecurity  end-->

        <!--        spring第三方支持 start-->
        <dependency>
            <groupId>org.springframework.social</groupId>
            <artifactId>spring-social-config</artifactId>
            <version>${spring.social.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.social</groupId>
            <artifactId>spring-social-core</artifactId>
            <version>${spring.social.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.social</groupId>
            <artifactId>spring-social-security</artifactId>
            <version>${spring.social.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.social</groupId>
            <artifactId>spring-social-web</artifactId>
            <version>${spring.social.version}</version>
        </dependency>
        <!--        spring第三方支持 end-->
        <!--        poi支持  start-->
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi</artifactId>
            <version>${poi.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-ooxml</artifactId>
            <version>${poi.version}</version>
        </dependency>
        <!--        poi支持  end-->

        <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpclient</artifactId>
            <version>4.5.6</version>
        </dependency>
        <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpcore</artifactId>
            <version>4.4.10</version>
        </dependency>

        <!--        json start-->
        <dependency>
            <groupId>org.json</groupId>
            <artifactId>json</artifactId>
            <version>${org.json.version}</version>
        </dependency>
        <!--        json end-->
        <!--        pdf读写支持 start-->
        <dependency>
            <groupId>com.itextpdf</groupId>
            <artifactId>itextpdf</artifactId>
            <version>${pdf.version}</version>
        </dependency>
        <!--        pdf读写支持 end-->

        <!--        邮件支持 start-->
        <dependency>
            <groupId>com.sun.mail</groupId>
            <artifactId>javax.mail</artifactId>
            <version>1.6.2</version>
        </dependency>
        <!--        邮件支持 end-->
        <dependency>
            <groupId>org.apache.velocity</groupId>
            <artifactId>velocity</artifactId>
            <version>1.7</version>
        </dependency>
        <dependency>
            <groupId>org.apache.velocity</groupId>
            <artifactId>velocity-tools</artifactId>
            <version>2.0</version>
        </dependency>

        <!--        activiti start-->
        <dependency>
            <groupId>org.activiti</groupId>
            <artifactId>activiti-engine</artifactId>
            <version>${activiti.version}</version>
            <exclusions>
                <exclusion>
                    <artifactId>mybatis</artifactId>
                    <groupId>org.mybatis</groupId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.activiti</groupId>
            <artifactId>activiti-spring</artifactId>
            <version>${activiti.version}</version>
        </dependency>
        <dependency>
            <groupId>org.activiti</groupId>
            <artifactId>activiti-modeler</artifactId>
            <version>${activiti.version}</version>
        </dependency>
        <dependency>
            <groupId>org.activiti</groupId>
            <artifactId>activiti-diagram-rest</artifactId>
            <version>${activiti.version}</version>
        </dependency>
        <dependency>
            <groupId>org.activiti</groupId>
            <artifactId>activiti-process-validation</artifactId>
            <version>${activiti.version}</version>
        </dependency>
        <dependency>
            <groupId>org.activiti</groupId>
            <artifactId>activiti-rest</artifactId>
            <version>${activiti.version}</version>
        </dependency>
        <dependency>
            <groupId>org.activiti</groupId>
            <artifactId>activiti-json-converter</artifactId>
            <version>${activiti.version}</version>
        </dependency>
        <dependency>
            <groupId>org.activiti</groupId>
            <artifactId>activiti-image-generator</artifactId>
            <version>${activiti.version}</version>
        </dependency>
        <dependency>
            <groupId>org.activiti</groupId>
            <artifactId>activiti-bpmn-model</artifactId>
            <version>${activiti.version}</version>
        </dependency>
        <dependency>
            <groupId>org.activiti</groupId>
            <artifactId>activiti-bpmn-converter</artifactId>
            <version>${activiti.version}</version>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.uuid</groupId>
            <artifactId>java-uuid-generator</artifactId>
            <version>3.1.4</version>
        </dependency>
        <dependency>
            <groupId>org.apache.xmlgraphics</groupId>
            <artifactId>batik-codec</artifactId>
            <version>1.7</version>
        </dependency>
        <dependency>
            <groupId>org.apache.xmlgraphics</groupId>
            <artifactId>batik-dom</artifactId>
            <version>1.7</version>
        </dependency>
        <dependency>
            <groupId>org.apache.xmlgraphics</groupId>
            <artifactId>batik-xml</artifactId>
            <version>1.7</version>
        </dependency>
        <dependency>
            <groupId>org.apache.xmlgraphics</groupId>
            <artifactId>batik-util</artifactId>
            <version>1.7</version>
        </dependency>
        <dependency>
            <groupId>org.apache.xmlgraphics</groupId>
            <artifactId>batik-gvt</artifactId>
            <version>1.7</version>
        </dependency>
        <dependency>
            <groupId>org.apache.xmlgraphics</groupId>
            <artifactId>batik-svggen</artifactId>
            <version>1.7</version>
        </dependency>
        <dependency>
            <groupId>org.apache.xmlgraphics</groupId>
            <artifactId>batik-parser</artifactId>
            <version>1.7</version>
        </dependency>
        <dependency>
            <groupId>org.apache.xmlgraphics</groupId>
            <artifactId>batik-transcoder</artifactId>
            <version>1.7</version>
        </dependency>
        <dependency>
            <groupId>org.apache.xmlgraphics</groupId>
            <artifactId>batik-svg-dom</artifactId>
            <version>1.7</version>
        </dependency>
        <!--activiti end-->
    </dependencies>


    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <classifier>exec</classifier>
                    <mainClass>com.zlx.bpms.BpmsPermissionWebApplication</mainClass>
                </configuration>
                <executions>
                    <execution>
                        <goals>
                            <goal>repackage</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
                <configuration>
                    <skip>true</skip>
                    <testFailureIgnore>true</testFailureIgnore>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>

修改application.properties文件,增加数据库配置,mybatis-plus相关配置等信息(关于mybatis-plus配置信息如有不懂的,可以在GitHub上搜索,为了方便也可以直接查看我的项目代码。)。启动项目
控制台出现Using generated security password: 71a6581e-ce07-4a08-895b-17d11e24b0b0这样一串日志,证明集成Security成功。
打开浏览器,访问项目地址,会看到如下页面:

到这里,也就是我们所做的一切都已经按照我们的预期顺利进行,那么由于时间有限,就先到这里结束了。稍后我会一一进行更新。喜欢的小伙伴动动你们的小手,帮忙点点支持。

posted @ 2020-03-15 16:27  喜欢你的眉眼微笑i  阅读(19313)  评论(2编辑  收藏  举报