SpringBoot2.x 集成 Spring Security

目前Web开发常用的两个安全框架:Apache Shiro 和 Spring Security,这里学习的是Spring Security,Spring Security本身是Spring社区的一个子架构,相对而言对Spring有更好的支持。

Spring Security官方文档:https://docs.spring.io/spring-security/site/docs/

安全框架基本概念:

  • “认证” (Authentication):身份认证/登录,验证用户是不是拥有相应的身份;
  • “授权”(Authorization) :授权,即权限验证,验证某个已认证的用户是否拥有某个权限;即判断用户是否能做事情,常见的如:验证某个用户是否拥有某个角色。

下面开始集成SpringSecurity到SpringBoot中

1. 引入Maven依赖

视图框架采用的SpringBoot推荐的Thymeleaf,Thymeleaf框架对Spring Security有扩展支持,只需要引入相应Jar就好。SpringBoot2.1.X版本默认集成的是Security5

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

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

<!--thymeleaf对security5的支持依赖-->
 <dependency>
    <groupId>org.thymeleaf.extras</groupId>
    <artifactId>thymeleaf-extras-springsecurity5</artifactId>
    <version>3.0.4.RELEASE</version>
 </dependency>

thymeleaf-extras-springsecurity5的使用可以参照文档:https://github.com/thymeleaf/thymeleaf-extras-springsecurity

说明:thymeleaf-extras-springsecurity5和thymeleaf-extras-springsecurity4有所不同,IDEA对5支持不好,于是我自己在页面中使用的还是4

2. 编写Security配置类

Spring Security比较重要的几个类

  • WebSecurityConfigurerAdapter:自定义Security策略,配置类需要继承这个类,实现其两个configure方法(认证和授权)
  • AuthenticationManagerBuilder:自定义认证策略
  • HttpSecurity:自定义授权策略
  • @EnableWebSecurity:开启WebSecurity模式
/**
 * 自定义Security配置类
 *
 * @author azure
 * @since 2019/10/12
 */
@EnableWebSecurity
public class MySecurityConfig extends WebSecurityConfigurerAdapter {

    /**
     * 认证
     */
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.inMemoryAuthentication() // 项目启动 账户-密码-角色 信息保存进内存中
                  .withUser("zhangsan").password("{noop}123456").roles("VIP1")
            .and().withUser("lisi").password("{noop}123456").roles("VIP1, VIP2")
            .and().withUser("wangwu").password(new BCryptPasswordEncoder()
                .encode("123456")).roles("VIP1", "VIP2", "VIP3");

        /*
          说明:
            1.这里采用的的是把用户角色保存在内存中,数据是写死的,当然数据可以从数据库中查出再写入内存中;
            2.随后定义的三个用户,没有用户定义了其用户名,密码和角色
            3.Security5默认要求密码使用加密,不加密的话就使用"{noop}123456"这样的写法,加密的话需要使用
                PasswordEncoder的实现类进行加密
         */
    }

    /**
     * 授权
     */
    @Override
    protected void configure(HttpSecurity http) throws Exception {
     // 禁止隧道 // 禁止跨域 // 禁止头部
     http.csrf().disable().cors().disable().headers().disable();

        // 所有的人都可以访问的路径
        http.authorizeRequests().antMatchers("/", "/webjars/**", "/static/**").permitAll()
                // VIP1的用户可以访问level1下的所有路径
                .antMatchers("/level1/**").hasRole("VIP1")
                // VIP2的用户可以访问level2下的所有路径
                .antMatchers("/level2/**").hasRole("VIP2")          // VIP3的用户可以访问level3下所有的路径
                .antMatchers("/level3/**").hasRole("VIP3");

        /*
         开启自动配置的登录功能,如果没有登录就会来到登录页面
            1. 会自动生成登录页面 /login
            2. 登录失败会自动重定向到 /login?error
         */
        http.formLogin()
            /*
            自定义登录页面设置
                1. 登录的路径还是设置成/login,否则算是自定义登录路径,其他的设置也需要改变
                   /login(get):到登录页,, 自定义的话就是 /authenticate(get)
                   /login(post):登录检查,,自定义的话就是 /authenticate(post)
                2. 可以自定义form表达提交的参数名称
                   默认username字段提交用户名,可以通过usernameParameter自定义
                   默认password字段提交密码,可以用过passwordParameter自定义
                3. loginProcessingUrl("/xxx") 可以自定义登录成功后跳转的路径
             */
            .loginPage("/login");

        /*
        开启自动配置的记住我功能
            1.登录成功后,将cookie发送给浏览器保存,以后登录带上这个cookie,只要通过检查就可以免登录
            2.点击注销之后会删除cookie
            3.rememberMe功能跟前端约定的表单提交名称是remember-me,可以通过rememberMeParameter自定义
         */
        http.rememberMe(); //.rememberMeParameter("remember")自定义表单提交名称为remember

        /*
         开启自动配置的退出功能:
            1. 访问/logout请求,用户注销,清楚session
            2. 注销成功后重定向到 login?logout,,可以通过logoutSuccessUrl("/")自定义
         */
        http.logout().logoutSuccessUrl("/");
    }
}

3. 页面端编写

页面引入thymeleaf对security支持的命名空间支持:xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity4,其中常用的属性和方法如下:

  • sec:authorize="isAuthenticated()":是否授权成功
  • sec:authentication="principal.authorities":获取用户所拥有的角色
  • sec:authentication="name":获取用户名字
  • sec:authorize="hasRole("xxx")":判断当前用户是否拥有指定角色

首页:主要是对用户权限的控制

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org"
      xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity4">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>首页</title>
</head>
<body>
    <h1 align="center">欢迎光临武林秘籍管理系统</h1>
    <div sec:authorize="!isAuthenticated()">
        <h2 align="center">游客您好,如果想查看武林秘籍 <a th:href="@{/login}">请登录</a></h2>
    </div>
    <div sec:authorize="isAuthenticated()">
        <h2 align="center">
            <span sec:authentication="name"></span>
            <small sec:authentication="principal.authorities"></small>
        </h2>
        <form th:action="@{/logout}" method="post">
            <input type="submit" value="退出">
        </form>
    </div>
    <hr>

    <div sec:authorize="hasRole(‘VIP1‘)">
        <h3>普通武功秘籍</h3>
        <ul>
            <li><a th:href="@{/level1/1}">罗汉拳</a></li>
            <li><a th:href="@{/level1/2}">武当长拳</a></li>
            <li><a th:href="@{/level1/3}">全真剑法</a></li>
        </ul>
    </div>

    <div sec:authorize="hasRole(‘VIP2‘)">
        <h3>高级武功秘籍</h3>
        <ul>
            <li><a th:href="@{/level2/1}">太极拳</a></li>
            <li><a th:href="@{/level2/2}">七伤拳</a></li>
            <li><a th:href="@{/level2/3}">梯云纵</a></li>
        </ul>
    </div>

    <div sec:authorize="hasRole(‘VIP3‘)">
        <h3>绝世武功秘籍</h3>
        <ul>
            <li><a th:href="@{/level3/1}">葵花宝典</a></li>
            <li><a th:href="@{/level3/2}">龟派气功</a></li>
            <li><a th:href="@{/level3/3}">独孤九剑</a></li>
        </ul>
    </div>
</body>
</html>

登录页:主要是登录路径和提交用户名密码的名称(security默认的是:/login,username,password,remember-me  但是都支持自定义)

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
    <meta name="description" content="">
    <title>登录</title>
    <link th:href="@{/webjars/bootstrap/4.3.1/css/bootstrap.css}" rel="stylesheet">
    <link th:href="@{/asserts/css/signin.css}" rel="stylesheet">
</head>
<body class="text-center">
    <form class="form-signin" th:action="@{/login}" method="post">
      <img class="mb-4" th:src="@{/asserts/images/bootstrap-solid.svg}" alt="" width="72" height="72">
      <h1 class="h3 mb-3 font-weight-normal">请登录</h1>
      <label for="username" class="sr-only">username</label>
      <input type="text" id="username" name="username" class="form-control" placeholder="username" required="" autofocus="">
      <label for="password" class="sr-only">Password</label>
      <input type="password" id="password" name="password" class="form-control" placeholder="password" required="">
      <div class="checkbox mb-3">
          <label>
              <input type="checkbox" value="remember-me"> 记住我
          </label>
      </div>
      <button class="btn btn-lg btn-primary btn-block" type="submit">登录</button>
      <p class="mt-5 mb-3 text-muted">© 2017-2018</p>
    </form>
</body>
</html>

4.参照

SpringBoot 2.x - SpringSecurity(内存管理版)

springboot2.1.2+springsecurity5.1.3+thymeleaf3.0.11 sec标签不生效

原文地址:https://www.cnblogs.com/gangbalei/p/11660551.html

时间: 2024-10-24 22:55:00

SpringBoot2.x 集成 Spring Security的相关文章

SpringBoot 集成Spring security

Spring security作为一种安全框架,使用简单,能够很轻松的集成到springboot项目中,下面讲一下如何在SpringBoot中集成Spring Security.使用gradle项目管理工具. 准备数据, CREATE TABLE `user` ( `uid` int(11) NOT NULL AUTO_INCREMENT, `username` varchar(255) DEFAULT NULL, `password` varchar(255) DEFAULT NULL, `r

SpringBoot集成Spring Security(4)——自定义表单登录

通过前面三篇文章,你应该大致了解了 Spring Security 的流程.你应该发现了,真正的 login 请求是由 Spring Security 帮我们处理的,那么我们如何实现自定义表单登录呢,比如添加一个验证码- 源码地址:https://github.com/jitwxs/blog_sample 文章目录 一.添加验证码 1.1 验证码 Servlet 1.2 修改 login.html 1.3 添加匿名访问 Url二.AJAX 验证三.过滤器验证 3.1 编写验证码过滤器 3.2 注

SpringBoot集成Spring Security(5)——权限控制

在第一篇中,我们说过,用户<–>角色<–>权限三层中,暂时不考虑权限,在这一篇,是时候把它完成了. 为了方便演示,这里的权限只是对角色赋予权限,也就是说同一个角色的用户,权限是一样的.当然了,你也可以精细化到为每一个用户设置权限,但是这不在本篇的探讨范围,有兴趣可以自己实验,原理都是一样的. 源码地址:https://github.com/jitwxs/blog_sample 文章目录 一.数据准备 1.1 创建 sys_permission 表 1.2 创建 POJO.Mappe

Spring Boot集成Spring Security

1.pom.xml文件<?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

springboot集成spring security实现restful风格的登录认证 附代码

一.文章简介 本文简要介绍了spring security的基本原理和实现,并基于springboot整合了spring security实现了基于数据库管理的用户的登录和登出,登录过程实现了验证码的校验功能. 完整代码地址:https://github.com/Dreamshf/spring-security.git 二.spring security框架简介 Spring Security是一个能够为基于Spring的企业应用系统提供声明式的安全访问控制解决方案的安全框架.主要包括:用户认证

SpringMVC 3.2集成Spring Security 3.2集成mybaties

目录结构如下 1.pom.xml <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 http://maven.apache.org/maven-v4_0_0.xsd">

SpringBoot集成Spring Security(1)——入门程序

因为项目需要,第一次接触 Spring Security,早就听闻 Spring Security 功能强大但上手困难,学习了几天出入门道,特整理这篇文章希望能让后来者少踩一点坑(本文附带实例程序,请放心食用) 本篇文章环境:SpringBoot 2.0 + Mybatis + Spring Security 5.0 源码地址:https://github.com/jitwxs/blog_sample文章目录 一.导入依赖二.创建数据库三.准备页面四.配置application.properti

Spring Security 3.2.x与Spring 4.0.x的Maven依赖管理

原文链接: Spring Security with Maven原文日期: 2013年04月24日翻译日期: 2014年06月29日翻译人员: 铁锚 1. 概述 本文通过实例为您介绍怎样使用 Maven 管理 Spring Security 和 Spring 的依赖关系.最新的Spring Security公布版本号能够在 Maven Central仓库 中找到. 译者建议訪问MVNRespotory中org.springframework.security链接.本文是 使用Maven管理Spr

spring security使用自定义登录界面后,不能返回到之前的请求界面的问题

昨天因为集成spring security oauth2,所以对之前spring security的配置进行了一些修改,然后就导致登录后不能正确跳转回被拦截的页面,而是返回到localhost根目录. 开始以为是被oauth2拦截了导致出了问题,但是security的拦截器是优先起作用的,所以这不可能. 最后实在没法只有打断点调试找毛病(下图为spring security登录后重定向至拦截前访问的url的实现原理流程) 图片是在这里看到的https://blog.csdn.net/zy_coo