Spring Boot中的SpringSecurity基础教程

目录
  • 一 SpringSecurity简介
  • 二 实战演示
    • 0. 环境 介绍
    • 1. 新建一个初始的springboot项目
    • 2. 导入thymeleaf依赖
    • 3. 导入静态资源
    • 4. 编写controller跳转
    • 5. 认证和授权
    • 6. 权限控制和注销
    • 7. 记住登录
    • 8. 定制登录页面
  • 三 完整代码
    • 3.1 pom配置文件
    • 3.2 RouterController.java
    • 3.3 SecurityConfig.java
    • 3.4 login.html
    • 3.5 index.html
    • 3.6 效果展示

一 SpringSecurity简介

  • Web开发中,虽然安全属于非共功能性需求,但也是应用非常重要的一部分。
  • 如果开发后期才考虑安全问题,就会有两方面的弊处:
  • 一方面,应用存在严重的安全漏洞,无法满足用户需求,可能造成用户隐私数据被攻击者窃取
  • 另一方面,应用的基本架构已经确定,要修复安全漏洞,可能需要对系统的架构做出比较重大的调整,会需要更多的开发时间,影响应用的发布进程
  • 结论:从应用开发的第一天就要把安全相关的因素考虑进来,并持续在整个应用的开发过程中
  • Spring Security是一个功能强大且高度可定制的身份验证和访问控制框架。它实际上是保护基于spring的应用程序的标准Spring Security是一个框架,侧重于为Java应用程序提供身份验证和授权。
  • Spring安全性的真正强大之处在于它可以轻松地扩展以满足定制需求
  • Spring 是一个非常流行和成功的 Java 应用开发框架。Spring Security 基于 Spring 框架,提供了一套Web 应用安全性的完整解决方案。一般来说,Web 应用的安全性包括用户认证(Authentication)和用户授权(Authorization)两个部分。
  • 用户认证指的是验证某个用户是否为系统中的合法主体,也就是说用户能否访问该系统。用户认证一般要求用户提供用户名和密码。系统通过校验用户名和密码来完成认证过程。
  • 用户授权指的是验证某个用户是否有权限执行某个操作。在一个系统中,不同用户所具有的权限是不同的。比如对一个文件来说,有的用户只能进行读取,而有的用户可以进行修改。一般来说,系统会为不同的用户分配不同的角色,而每个角色则对应一系列的权限。
  • 在用户认证方面,SpringSecurity 框架支持主流的认证方式,包括==HTTP 基本认证、HTTP 表单验证、HTTP 摘要认证、OpenID和LDAP ==等。
  • 在用户授权方面,Spring Security 提供了基于角色的访问控制和访问控制列表(Access Control List,ACL),可以对应用中的领域对象进行细粒度的控制。
  • Spring Security 是针对Spring项目的安全框架,也是Spring Boot底层安全模块默认的技术选型,可以实现强大的Web安全控制,对于安全控制,仅需要引入 spring-boot-starter-security 模块,进行少量的配置,即可实现强大的安全管理!
  • 几个重要的类
  • WebSecurityConfigurerAdapter: 自定义Security策略
  • AuthenticationManagerBuilder:自定义认证策略
  • @EnableWebSecurity:开启WebSecurity模式
  • Spring Security的两个主要目标是 “认证” 和 “授权”(访问控制)
  • “认证”(Authentication)
  • 身份验证是关于验证您的凭据,如用户名/用户ID和密码,以验证您的身份。
  • 身份验证通常通过用户名和密码完成,有时与身份验证因素结合使用。
  • “授权” (Authorization)
  • 授权发生在系统成功验证您的身份后,最终会授予您访问资源(如信息,文件,数据库,资金,位置,几乎任何内容)的完全权限。

二 实战演示

0. 环境 介绍

  • jdk 1.8
  • Spring Boot 2.0.9.RELEASE

1. 新建一个初始的springboot项目

2. 导入thymeleaf依赖

<!--thymeleaf-->
<dependency>
    <groupId>org.thymeleaf</groupId>
    <artifactId>thymeleaf-spring5</artifactId>
</dependency>
<dependency>
    <groupId>org.thymeleaf.extras</groupId>
    <artifactId>thymeleaf-extras-java8time</artifactId>
</dependency>

3. 导入静态资源

4. 编写controller跳转

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;

/**
 * @author 缘友一世
 * date 2022/9/11-21:56
 */
@Controller
public class RouterController {
    @RequestMapping({"/","/index"})
    public String index() {
         return "index";
    }
    @RequestMapping("/toLogin")
    public String toLogin() {
        return "views/login";
    }
    @RequestMapping("/level1/{id}")
    public String level1(@PathVariable("id") int id) {
        return "views/level1/"+id;
    }
    @RequestMapping("/level2/{id}")
    public String level2(@PathVariable("id") int id) {
        return "views/level2/"+id;
    }
    @RequestMapping("/level3/{id}")
    public String level3(@PathVariable("id") int id) {
        return "views/level3/"+id;
    }
}

5. 认证和授权

  • Spring Security 增加上认证和授权的功能

引入Spring Security模块

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

2.编写 Spring Security 配置类

参考官网

帮助文档



import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;

/**
 * @author 缘友一世
 * date 2022/9/11-22:13
 */
// 开启WebSecurity模式
@EnableWebSecurity //AOP 拦截器
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    //链式编程
    @Override
    protected void configure(HttpSecurity http) throws Exception {

    }

import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;

/**
 * @author 缘友一世
 * date 2022/9/11-22:13
 */
// 开启WebSecurity模式
@EnableWebSecurity //AOP 拦截器
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    //链式编程
    @Override
    protected void configure(HttpSecurity http) throws Exception {

    }

3.定制请求的授权规则

 //链式编程
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        //首页所有人可以访问,功能页面只有对应的人可以访问
        //请求授权的规则
        http.authorizeRequests().antMatchers("/").permitAll()
                .antMatchers("/level1/**").hasRole("vip1")
                .antMatchers("/level2/**").hasRole("vip2")
                .antMatchers("/level3/**").hasRole("vip3");
    }

4.测试一下:发现除了首页都进不去了!因为我们目前没有登录的角色,因为请求需要登录的角色拥有对应的权限才可以

5.在 configure() 方法中加入以下配置,开启自动配置的登录功能

//没有权限默认回到登录页面,需要开启登录的页面
http.formLogin();

6.定义认证规则,重写 configure(AuthenticationManagerBuilder auth) 方法

  • 要将前端传过来的密码进行某种方式加密,否则就无法登录

/**
     * 要将前端传过来的密码进行某种方式加密,否则就无法登录
     * @param auth
     * @throws Exception
     */
    @Override //认证 密码编码 PassWordEncoder
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {

        auth.inMemoryAuthentication().passwordEncoder(new BCryptPasswordEncoder())
                .withUser("yang").password(new BCryptPasswordEncoder().encode("123456")).roles("vip2","vip3")
                .and()
                .withUser("root").password(new BCryptPasswordEncoder().encode("123456")).roles("vip1","vip2","vip3")
                .and()
                .withUser("guest").password(new BCryptPasswordEncoder().encode("123456")).roles("vip1");
    }

6. 权限控制和注销

开启自动配置的注销的功能

@EnableWebSecurity //AOP 拦截器
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    //链式编程
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        //首页所有人可以访问,功能页面只有对应的人可以访问
        //请求授权的规则
        http.authorizeRequests().antMatchers("/").permitAll()
                .antMatchers("/level1/**").hasRole("vip1")
                .antMatchers("/level2/**").hasRole("vip2")
                .antMatchers("/level3/**").hasRole("vip3");
        //注销 跳到首页
        http.logout().logoutSuccessUrl("/");

在前端,增加一个注销的按钮, index.html 导航栏中

<a class="item" th:href="@{/logout}" rel="external nofollow"  rel="external nofollow"  rel="external nofollow" >
	<i class="address card icon"></i> 注销
</a>

不同身份的用户,显示不同内容

  • 用户没有登录的时候,导航栏上只显示登录按钮,用户登录之后,导航栏可以显示登录的用户信息及注销按钮
  • sec:authorize=“isAuthenticated()”:是否认证登录! 来显示不同的页面
  • 导入依赖
 <!--thymeleaf-security整合包-->
    <!-- https://mvnrepository.com/artifact/org.thymeleaf.extras/thymeleaf-extras-springsecurity4 -->
    <dependency>
        <groupId>org.thymeleaf.extras</groupId>
        <artifactId>thymeleaf-extras-springsecurity4</artifactId>
        <version>3.0.4.RELEASE</version>
    </dependency>

在前端页面导入命名空间

<html lang="en" xmlns:th="http://www.thymeleaf.org"
  xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity4">

修改导航栏,增加认证判断

<!--index.html-->
<!--登录注销-->
            <div class="right menu">
                <!--如果未登录-->
                <div sec:authorize="!isAuthenticated()">
                    <a class="item" th:href="@{/toLogin}" rel="external nofollow"  rel="external nofollow" >
                        <i class="address card icon"></i> 登录
                    </a>
                </div>

                <!--如果登陆了:用户名、注销-->
                <!--当登录、用户名、退出同时出现,是spring版本太高了,降至2.0.9/7 就能正常了-->
                <div sec:authorize="isAuthenticated()">
                    <a class="item" >
                        用户名:<span sec:authentication="name"></span>
                    </a>
                </div>
                <div sec:authorize="isAuthenticated()">
                    <a class="item" th:href="@{/logout}" rel="external nofollow"  rel="external nofollow"  rel="external nofollow" >
                        <i class="sign-out icon"></i> 注销
                    </a>
                </div>
            </div>

如果注销404,就是因为它默认防止csrf跨站请求伪造,因为会产生安全问题,我们可以将请求改为post表单提交,或者在spring security中关闭csrf功能;我们试试

	//链式编程
	    @Override
	    protected void configure(HttpSecurity http) throws Exception {
	        //首页所有人可以访问,功能页面只有对应的人可以访问
	        //请求授权的规则
	        http.authorizeRequests().antMatchers("/").permitAll()
	                .antMatchers("/level1/**").hasRole("vip1")
	                .antMatchers("/level2/**").hasRole("vip2")
	                .antMatchers("/level3/**").hasRole("vip3");
	        //没有权限默认回到登录页面,需要开启登录的页面
	        http.formLogin().loginProcessingUrl("/login");

	        //防止网站攻击 csrf--跨站请求伪造
	        http.csrf().disable();
	        //注销 跳到首页
	        http.logout().logoutSuccessUrl("/");
	    }

角色功能块

 <div>
        <br>
        <div class="ui three column stackable grid">

            <div class="column" sec:authorize="hasRole('vip1')">
                <div class="ui raised segment">
                    <div class="ui">
                        <div class="content">
                            <h5 class="content">Level 1</h5>
                            <hr>
                            <div><a th:href="@{/level1/1}" rel="external nofollow"  rel="external nofollow" ><i class="bullhorn icon"></i> Level-1-1</a></div>
                            <div><a th:href="@{/level1/2}" rel="external nofollow"  rel="external nofollow" ><i class="bullhorn icon"></i> Level-1-2</a></div>
                            <div><a th:href="@{/level1/3}" rel="external nofollow"  rel="external nofollow" ><i class="bullhorn icon"></i> Level-1-3</a></div>
                        </div>
                    </div>
                </div>
            </div>

            <div class="column" sec:authorize="hasRole('vip2')">
                <div class="ui raised segment">
                    <div class="ui">
                        <div class="content">
                            <h5 class="content">Level 2</h5>
                            <hr>
                            <div><a th:href="@{/level2/1}" rel="external nofollow"  rel="external nofollow" ><i class="bullhorn icon"></i> Level-2-1</a></div>
                            <div><a th:href="@{/level2/2}" rel="external nofollow"  rel="external nofollow" ><i class="bullhorn icon"></i> Level-2-2</a></div>
                            <div><a th:href="@{/level2/3}" rel="external nofollow"  rel="external nofollow" ><i class="bullhorn icon"></i> Level-2-3</a></div>
                        </div>
                    </div>
                </div>
            </div>

            <div class="column" sec:authorize="hasRole('vip3')">
                <div class="ui raised segment">
                    <div class="ui">
                        <div class="content">
                            <h5 class="content">Level 3</h5>
                            <hr>
                            <div><a th:href="@{/level3/1}" rel="external nofollow"  rel="external nofollow" ><i class="bullhorn icon"></i> Level-3-1</a></div>
                            <div><a th:href="@{/level3/2}" rel="external nofollow"  rel="external nofollow" ><i class="bullhorn icon"></i> Level-3-2</a></div>
                            <div><a th:href="@{/level3/3}" rel="external nofollow"  rel="external nofollow" ><i class="bullhorn icon"></i> Level-3-3</a></div>
                        </div>
                    </div>
                </div>
            </div>

        </div>
    </div>

7. 记住登录

开启记住我功能

//链式编程
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        //首页所有人可以访问,功能页面只有对应的人可以访问
        //请求授权的规则
        http.authorizeRequests().antMatchers("/").permitAll()
                .antMatchers("/level1/**").hasRole("vip1")
                .antMatchers("/level2/**").hasRole("vip2")
                .antMatchers("/level3/**").hasRole("vip3");
        //没有权限默认回到登录页面,需要开启登录的页面
        http.formLogin().loginProcessingUrl("/login");// 登陆表单提交请求

        //防止网站攻击 csrf--跨站请求伪造
        http.csrf().disable();
        //注销 跳到首页
        http.logout().logoutSuccessUrl("/");
        //开启记住功能 cookie默认保持两周 自定义接收前端的参数
        http.rememberMe().rememberMeParameter("remember");
    }

原理:登录成功后,将cookie发送给浏览器保存,以后登录带上这个cookie,只要通过检查就可以免登录了。如果点击注销,则会删除这个cookie

8. 定制登录页面

在登录页配置后面指定.loginPage

<form th:action="@{/login}" method="post">
    <div class="field">
        <label>Username</label>
        <div class="ui left icon input">
            <input type="text" placeholder="Username" name="username">
            <i class="user icon"></i>
        </div>
    </div>
    <div class="field">
        <label>Password</label>
        <div class="ui left icon input">
            <input type="password" name="password">
            <i class="lock icon"></i>
        </div>
    </div>
    <div class="field">
        <input type="checkbox" name="remember"> 记住我
    </div>
    <input type="submit" class="ui blue submit button"/>
</form>

login.html 配置提交请求及方式,方式必须为post

//链式编程
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        //首页所有人可以访问,功能页面只有对应的人可以访问
        //请求授权的规则
        http.authorizeRequests().antMatchers("/").permitAll()
                .antMatchers("/level1/**").hasRole("vip1")
                .antMatchers("/level2/**").hasRole("vip2")
                .antMatchers("/level3/**").hasRole("vip3");
        //没有权限默认回到登录页面,需要开启登录的页面
        http.formLogin().loginPage("/toLogin");

        //防止网站攻击 csrf--跨站请求伪造
        http.csrf().disable();
        //注销 跳到首页
        http.logout().logoutSuccessUrl("/");
        //开启记住功能 cookie默认保持两周 自定义接收前端的参数
        http.rememberMe().rememberMeParameter("remember");
    }

配置接收登录的用户名和密码的参数!

http.formLogin()
.usernameParameter("username")
.passwordParameter("password")
.loginPage("/toLogin")
.loginProcessingUrl("/login"); // 登陆表单提交请求

在登录页增加记住我的多选框

<input type="checkbox" name="remember"> 记住我

后端验证处理

//定制记住我的参数!
http.rememberMe().rememberMeParameter("remember");

三 完整代码

3.1 pom配置文件

<dependencies>
   <!--thymeleaf-security整合包-->
    <!-- https://mvnrepository.com/artifact/org.thymeleaf.extras/thymeleaf-extras-springsecurity4 -->
    <dependency>
        <groupId>org.thymeleaf.extras</groupId>
        <artifactId>thymeleaf-extras-springsecurity4</artifactId>
        <version>3.0.4.RELEASE</version>
    </dependency>

    <!--thymeleaf-->
    <dependency>
        <groupId>org.thymeleaf</groupId>
        <artifactId>thymeleaf-spring5</artifactId>
    </dependency>
    <dependency>
        <groupId>org.thymeleaf.extras</groupId>
        <artifactId>thymeleaf-extras-java8time</artifactId>
    </dependency>

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

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

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
</dependencies>

3.2 RouterController.java

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;

/**
 * @author 缘友一世
 * date 2022/9/11-21:56
 */
@Controller
public class RouterController {
    @RequestMapping({"/","/index"})
    public String index() {
         return "index";
    }
    @RequestMapping("/toLogin")
    public String toLogin() {
        return "views/login";
    }
    @RequestMapping("/level1/{id}")
    public String level1(@PathVariable("id") int id) {
        return "views/level1/"+id;
    }
    @RequestMapping("/level2/{id}")
    public String level2(@PathVariable("id") int id) {
        return "views/level2/"+id;
    }
    @RequestMapping("/level3/{id}")
    public String level3(@PathVariable("id") int id) {
        return "views/level3/"+id;
    }
}

3.3 SecurityConfig.java

import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;

/**
 * @author 缘友一世
 * date 2022/9/11-22:13
 */

@EnableWebSecurity //AOP 拦截器
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    //链式编程
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        //首页所有人可以访问,功能页面只有对应的人可以访问
        //请求授权的规则
        http.authorizeRequests().antMatchers("/").permitAll()
                .antMatchers("/level1/**").hasRole("vip1")
                .antMatchers("/level2/**").hasRole("vip2")
                .antMatchers("/level3/**").hasRole("vip3");
        //没有权限默认回到登录页面,需要开启登录的页面
        http.formLogin().usernameParameter("username")
                        .passwordParameter("password")
                        .loginPage("/toLogin")
                		.loginProcessingUrl("/login");

        //防止网站攻击 csrf--跨站请求伪造
        http.csrf().disable();
        //注销 跳到首页
        http.logout().logoutSuccessUrl("/");
        //开启记住功能 cookie默认保持两周 自定义接收前端的参数
        http.rememberMe().rememberMeParameter("remember");
    }

	/**
     * 要将前端传过来的密码进行某种方式加密,否则就无法登录
     * @param auth
     * @throws Exception
     */
    @Override //认证 密码编码 PassWordEncoder
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {

        auth.inMemoryAuthentication().passwordEncoder(new BCryptPasswordEncoder())
                .withUser("yang").password(new BCryptPasswordEncoder().encode("123456")).roles("vip2","vip3")
                .and()
                .withUser("root").password(new BCryptPasswordEncoder().encode("123456")).roles("vip1","vip2","vip3")
                .and()
                .withUser("guest").password(new BCryptPasswordEncoder().encode("123456")).roles("vip1");
    }
}

3.4 login.html

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
    <title>登录</title>
    <!--semantic-ui-->
    <link href="https://cdn.bootcss.com/semantic-ui/2.4.1/semantic.min.css" rel="external nofollow"  rel="external nofollow"  rel="stylesheet">
</head>
<body>

<!--主容器-->
<div class="ui container">

    <div class="ui segment">

        <div style="text-align: center">
            <h1 class="header">登录</h1>
        </div>

        <div class="ui placeholder segment">
            <div class="ui column very relaxed stackable grid">
                <div class="column">
                    <div class="ui form">
                        <form th:action="@{/login}" method="post">
                            <div class="field">
                                <label>Username</label>
                                <div class="ui left icon input">
                                    <input type="text" placeholder="Username" name="username">
                                    <i class="user icon"></i>
                                </div>
                            </div>
                            <div class="field">
                                <label>Password</label>
                                <div class="ui left icon input">
                                    <input type="password" name="password">
                                    <i class="lock icon"></i>
                                </div>
                            </div>
                            <div class="field">
                                <input type="checkbox" name="remember"> 记住我
                            </div>
                            <input type="submit" class="ui blue submit button"/>
                        </form>
                    </div>
                </div>
            </div>
        </div>

        <div style="text-align: center">
            <div class="ui label">
                </i>注册
            </div>
            <br><br>
            <small>blog.kuangstudy.com</small>
        </div>
        <div class="ui segment" style="text-align: center">
            <h3>Spring Security Study</h3>
        </div>
    </div>
</div>

<script th:src="@{/qinjiang/js/jquery-3.1.1.min.js}"></script>
<script th:src="@{/qinjiang/js/semantic.min.js}"></script>

</body>
</html>

3.5 index.html

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org"
      xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity4">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
    <title>首页</title>
    <!--semantic-ui-->
    <link href="https://cdn.bootcss.com/semantic-ui/2.4.1/semantic.min.css" rel="external nofollow"  rel="external nofollow"  rel="stylesheet">
    <link th:href="@{/qinjiang/css/qinstyle.css}" rel="external nofollow"  rel="stylesheet">
</head>
<body>

<!--主容器-->
<div class="ui container">

    <div class="ui segment" id="index-header-nav" th:fragment="nav-menu">
        <div class="ui secondary menu">
            <a class="item"  th:href="@{/index}" rel="external nofollow" >首页</a>

            <!--登录注销-->
            <div class="right menu">
                <!--如果未登录-->
                <div sec:authorize="!isAuthenticated()">
                    <a class="item" th:href="@{/toLogin}" rel="external nofollow"  rel="external nofollow" >
                        <i class="address card icon"></i> 登录
                    </a>
                </div>

                <!--如果登陆了:用户名、注销-->
                <!--当登录、用户名、退出同时出现,是spring版本太高了,降至2.0.9/7 就能正常了-->
                <div sec:authorize="isAuthenticated()">
                    <a class="item" >
                        用户名:<span sec:authentication="name"></span>
                    </a>
                </div>
                <div sec:authorize="isAuthenticated()">
                    <a class="item" th:href="@{/logout}" rel="external nofollow"  rel="external nofollow"  rel="external nofollow" >
                        <i class="sign-out icon"></i> 注销
                    </a>
                </div>
                <!--已登录
                <a th:href="@{/usr/toUserCenter}" rel="external nofollow" >
                    <i class="address card icon"></i> admin
                </a>
                -->
            </div>
        </div>
    </div>

    <div class="ui segment" style="text-align: center">
        <h3>Spring Security Study</h3>
    </div>

    <div>
        <br>
        <div class="ui three column stackable grid">

            <div class="column" sec:authorize="hasRole('vip1')">
                <div class="ui raised segment">
                    <div class="ui">
                        <div class="content">
                            <h5 class="content">Level 1</h5>
                            <hr>
                            <div><a th:href="@{/level1/1}" rel="external nofollow"  rel="external nofollow" ><i class="bullhorn icon"></i> Level-1-1</a></div>
                            <div><a th:href="@{/level1/2}" rel="external nofollow"  rel="external nofollow" ><i class="bullhorn icon"></i> Level-1-2</a></div>
                            <div><a th:href="@{/level1/3}" rel="external nofollow"  rel="external nofollow" ><i class="bullhorn icon"></i> Level-1-3</a></div>
                        </div>
                    </div>
                </div>
            </div>

            <div class="column" sec:authorize="hasRole('vip2')">
                <div class="ui raised segment">
                    <div class="ui">
                        <div class="content">
                            <h5 class="content">Level 2</h5>
                            <hr>
                            <div><a th:href="@{/level2/1}" rel="external nofollow"  rel="external nofollow" ><i class="bullhorn icon"></i> Level-2-1</a></div>
                            <div><a th:href="@{/level2/2}" rel="external nofollow"  rel="external nofollow" ><i class="bullhorn icon"></i> Level-2-2</a></div>
                            <div><a th:href="@{/level2/3}" rel="external nofollow"  rel="external nofollow" ><i class="bullhorn icon"></i> Level-2-3</a></div>
                        </div>
                    </div>
                </div>
            </div>

            <div class="column" sec:authorize="hasRole('vip3')">
                <div class="ui raised segment">
                    <div class="ui">
                        <div class="content">
                            <h5 class="content">Level 3</h5>
                            <hr>
                            <div><a th:href="@{/level3/1}" rel="external nofollow"  rel="external nofollow" ><i class="bullhorn icon"></i> Level-3-1</a></div>
                            <div><a th:href="@{/level3/2}" rel="external nofollow"  rel="external nofollow" ><i class="bullhorn icon"></i> Level-3-2</a></div>
                            <div><a th:href="@{/level3/3}" rel="external nofollow"  rel="external nofollow" ><i class="bullhorn icon"></i> Level-3-3</a></div>
                        </div>
                    </div>
                </div>
            </div>

        </div>
    </div>

</div>
<script th:src="@{/qinjiang/js/jquery-3.1.1.min.js}"></script>
<script th:src="@{/qinjiang/js/semantic.min.js}"></script>

</body>
</html>

3.6 效果展示

到此这篇关于Spring Boot中的SpringSecurity学习的文章就介绍到这了,更多相关Spring Boot之SpringSecurity内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • SpringSecurity+JWT实现前后端分离的使用详解

    创建一个配置类 SecurityConfig 继承 WebSecurityConfigurerAdapter package top.ryzeyang.demo.common.config; import org.springframework.context.annotation.Bean; import org.springframework.security.access.hierarchicalroles.RoleHierarchy; import org.springframework

  • 详解SpringSecurity如何实现前后端分离

    目录 Spring Security存在的问题 改造Spring Security的认证方式 1. 登录请求改成JSON方式 1.1 新建JSON版Filter - JsonUsernamePasswordAuthenticationFilter 1.2 新建Configurer来注册Filter - JsonUsernamePasswordLoginConfigurer 1.3 将自定义Configurer注册到HttpSecurity上 2. 关闭页面重定向 2.1 当前用户未登录 2.2

  • SpringSecurity导致SpringBoot跨域失效的问题解决

    目录 1.CORS 是什么 2.预检请求 3.三种配置的方式 3.1 @CrossOrigin 注解 3.2 实现 WebMvcConfigurer.addCorsMappings 方法 3.3 注入 CorsFilter 4.Spring Security 中的配置 5.这些配置有什么区别 5.1 Filter 与 Interceptor 5.2 WebMvcConfigurer.addCorsMappings 方法做了什么 5.2.1 注入 CORS 配置 5.2.2 获取 CORS 配置

  • SpringSecurity自定义登录成功处理

    有时候页面跳转并不能满足我们,特别是在前后端分离开发中就不需要成功之后跳转页面.只需要给前端返回一个JSON通知登录成功还是失败与否.这个试试可以通过自定义AuthenticationSuccessHandler实现 修改WebSecurityConfigurer successHandler package com.example.config; import com.example.handler.MyAuthenticationSuccessHandler; import org.spri

  • springSecurity实现简单的登录功能

    前言 1.不使用数据库,实现一个简单的登录功能,只有在登录后才能访问我们的接口2.springSecurity提供了一种基于内存的验证方法(使用自己定义的用户,不使用默认的) 一.实现用户创建,登陆后才能访问接口(注重用户认证) 1.定义一个内存用户,不使用默认用户 重写configure(AuthenticationManagerBuilder auth)方法,实现在内存中定义一个 (用户名/密码/权限:admin/123456/admin) 的用户 package com.example.s

  • SpringBoot+Vue前后端分离,使用SpringSecurity完美处理权限问题的解决方法

    当前后端分离时,权限问题的处理也和我们传统的处理方式有一点差异.笔者前几天刚好在负责一个项目的权限管理模块,现在权限管理模块已经做完了,我想通过5-6篇文章,来介绍一下项目中遇到的问题以及我的解决方案,希望这个系列能够给小伙伴一些帮助.本系列文章并不是手把手的教程,主要介绍了核心思路并讲解了核心代码,完整的代码小伙伴们可以在GitHub上star并clone下来研究.另外,原本计划把项目跑起来放到网上供小伙伴们查看,但是之前买服务器为了省钱,内存只有512M,两个应用跑不起来(已经有一个V部落开

  • Spring Boot中的SpringSecurity基础教程

    目录 一 SpringSecurity简介 二 实战演示 0. 环境 介绍 1. 新建一个初始的springboot项目 2. 导入thymeleaf依赖 3. 导入静态资源 4. 编写controller跳转 5. 认证和授权 6. 权限控制和注销 7. 记住登录 8. 定制登录页面 三 完整代码 3.1 pom配置文件 3.2 RouterController.java 3.3 SecurityConfig.java 3.4 login.html 3.5 index.html 3.6 效果展

  • Spring Boot中使用JDBC Templet的方法教程

    前言 Spring 的 JDBC Templet 是 Spring 对 JDBC 使用的一个基本的封装.他主要是帮助程序员实现了数据库连接的管理,其余的使用方式和直接使用 JDBC 没有什么大的区别. 业务需求 JDBC 的使用大家都比较熟悉了.这里主要为了演示在 SpringBoot 中使用 Spring JDBC Templet 的步骤,所以我们就设计一个简单的需求.一个用户对象的 CURD 的操作.对象有两个属性,一个属性是id,一个属性是名称.存储在 MySQL 的 auth_user

  • Spring Boot中使用RabbitMQ的示例代码

    很久没有写Spring Boot的内容了,正好最近在写Spring Cloud Bus的内容,因为内容会有一些相关性,所以先补一篇关于AMQP的整合. Message Broker与AMQP简介 Message Broker是一种消息验证.传输.路由的架构模式,其设计目标主要应用于下面这些场景: 消息路由到一个或多个目的地 消息转化为其他的表现方式 执行消息的聚集.消息的分解,并将结果发送到他们的目的地,然后重新组合相应返回给消息用户 调用Web服务来检索数据 响应事件或错误 使用发布-订阅模式

  • Spring Boot中扩展XML请求与响应的支持详解

    前言 在之前的所有Spring Boot教程中,我们都只提到和用到了针对HTML和JSON格式的请求与响应处理.那么对于XML格式的请求要如何快速的在Controller中包装成对象,以及如何以XML的格式返回一个对象呢? 什么是xml文件格式 我们要给对方传输一段数据,数据内容是"too young,too simple,sometimes naive",要将这段话按照属性拆分为三个数据的话,就是,年龄too young,阅历too simple,结果sometimes naive.

  • Spring Security 在 Spring Boot 中的使用详解【集中式】

    1.1 准备 1.1.1 创建 Spring Boot 项目   创建好一个空的 Spring Boot 项目之后,写一个 controller 验证此时是可以直接访问到该控制器的. 1.1.2 引入 Spring Security   在 Spring Boot 中引入 Spring Security 是相当简单的,可以在用脚手架创建项目的时候勾选,也可以创建完毕后在 pom 文件中加入相关依赖. <dependency> <groupId>org.springframework

  • Spring Boot 员工管理系统超详细教程(源码分享)

    员工管理系统 1.准备工作 资料下载 内含源码 + 笔记 + web素材 源码下载地址: http://xiazai.jb51.net/202105/yuanma/javaguanli_jb51.rar 笔记 素材 源码 1.1.导入资源 将文件夹中的静态资源导入idea中 位置如下 1.2.编写pojo层 员工表 //员工表 @Data @NoArgsConstructor public class Employee { private Integer id; private String l

  • 如何在Spring Boot中使用MQTT

    为什么选择MQTT MQTT的定义相信很多人都能讲的头头是道,本文章也不讨论什么高大上的东西,旨在用最简单直观的方式让每一位刚接触的同行们可以最快的应用起来 先从使用MQTT需要什么开始分析: 消息服务器 不同应用/设备之间的频繁交互 可能涉及一对多的消息传递 根据上面列举的这三点,我们大概可以了解到, MQTT最适合的场景是消息做为系统的重要组成部分,且参与着系统关键业务逻辑的情形 MQTT, 启动! 既然决定使用它,我们首先要研究的是如何让MQTT正常工作,毕竟它不是简单的在maven里加入

  • Spring Boot中使用Actuator的/info端点输出Git版本信息

    对于Spring Boot的Actuator模块相信大家已经不陌生了,尤其对于其中的/health./metrics等强大端点已经不陌生(如您还不了解Actuator模块,建议先阅读<Spring Boot Actuator监控端点小结>).但是,其中还有一个比较特殊的端点/info经常被大家所忽视,因为从最初的理解,它主要用来输出application.properties配置文件中通过info前缀来定义的一些属性,由于乍看之下可能想不到太多应用场景,只是被用来暴露一些应用的基本信息,而基本

  • Spring Boot中使用Spring-data-jpa实现数据库增删查改

    在实际开发过程中,对数据库的操作无非就"增删改查".就最为普遍的单表操作而言,除了表和字段不同外,语句都是类似的,开发人员需要写大量类似而枯燥的语句来完成业务逻辑. 为了解决这些大量枯燥的数据操作语句,我们第一个想到的是使用ORM框架,比如:Hibernate.通过整合Hibernate之后,我们以操作Java实体的方式最终将数据改变映射到数据库表中. 为了解决抽象各个Java实体基本的"增删改查"操作,我们通常会以泛型的方式封装一个模板Dao来进行抽象简化,但是这

  • 详解spring boot中使用JdbcTemplate

    本文将介绍如何将spring boot 与 JdbcTemplate一起工作. Spring对数据库的操作在jdbc上面做了深层次的封装,使用spring的注入功能,可以把DataSource注册到JdbcTemplate之中. JdbcTemplate 是在JDBC API基础上提供了更抽象的封装,并提供了基于方法注解的事务管理能力. 通过使用SpringBoot自动配置功能并代替我们自动配置beans. 数据源配置 在maven中,我们需要增加spring-boot-starter-jdbc

随机推荐