zoukankan      html  css  js  c++  java
  • 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("{noop}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" name="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标签不生效

     springsecurity5+thymeleaf3的sec:authorize标签问题

  • 相关阅读:
    父子组件双向通讯
    高德地图采坑实践之文本标记点击事件左半边不生效(已解决)
    高德地图 location字段控制台显示 为字符串类型 实际为对象
    允许长单词、数字、URL换行到下一行
    python 格式化输出详解(占位符:%、format、f表达式)——上篇 理论篇
    python tkinter实现俄罗斯方块 基础版
    python递归三战:Sierpinski Triangle、Tower of Hanoi、Maze Exploring
    python(pygame)滑稽大战(类似飞机大战) 教程
    编辑器测试-TinyMCE
    封装cookie localStorage sessionStorage
  • 原文地址:https://www.cnblogs.com/gangbalei/p/11660551.html
Copyright © 2011-2022 走看看