• SpringBoot与(Security)安全


    1.简介

    应用程序的两个主要区域

    认证(Authentication):

    是建立一个它声明的主体的过程(一个“主体” 一般是指用户,设备或一些可以在你的应用程序中执行动作的其他系统)

    证明用户的身份,当用户登录之后,系统来查验用户名和密码,以此来证明你有对应身份,这个过程就是认证。

    授权 (Authorization)

    指确定一个主体是否允许在你的应用程序执行一个动作的过程。为了抵达需要授权的店,主体的身份已经有认证过程建立

    指的是你能够干什么 ,有什么样的访问权限。

    主要是几个类:

    WebSecurityConfigurerAdapter:自定义Security策略
    AuthenticationManagerBuilder:自定义认证策略
    @EnableWebSecurity:开启WebSecurity模式

    2.使用

    引入SpringSecurity;

    编写SpringSecurity的配置类;

    1. 继承WebSecurityConfigurerAdapter
    2. 在配置类上写上注解 @EnableWebSecurity

    控制请求的访问权限:

    • 需要重写方法
    1. 定制请求的授权规则

    2. 开启自动配置登录功能 :如果没有登录,没有权限就会到登录页面

      1. /login请求来到登录页
      2. 重定向到/login?error 表示登录失败
      3. 更多功能
    3. 开启自动配置的注销功能

      http.logout().logoutSuccessUrl("/");  //注销成功之后 ,来到首页
      
      1. 访问 /logout 表示用户注销,清空session
      2. 注销成功会返回 /login?logout
      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");
    
            //开启自动配置登录功能
            http.formLogin();
            //1、/login请求来到登录页
            //2、重定向到/login?error 表示登录失败
            //3、更多功能
            //4、默认post形式的/login代表处理登录
            //5、一旦定制loginPage;name   loginPage的post请求就是登录
            
            //    开启自动配置的注销功能
             //防止网站攻击
            http.csrf().disable();
            http.logout();
    

    定义认证规则

    1. 需要重写 方法, 配置对应的账号密码 以及角色

      //定义认证规则
          @Override
          protected void configure(AuthenticationManagerBuilder auth) throws Exception {
              auth.inMemoryAuthentication().passwordEncoder(new BCryptPasswordEncoder())
                      .withUser("zhangsan").password(new BCryptPasswordEncoder().encode("123456")).roles("VIP1","VIP2")
                      .and()
                      .withUser("lisi").password(new BCryptPasswordEncoder().encode("123456")).roles("VIP2","VIP3")
                      .and()
                      .withUser("wangwu").password(new BCryptPasswordEncoder().encode("123456")).roles("VIP1","VIP3");
          }
      

    3.thymeleaf整合security

    pom.xml文件中引入依赖

    <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">
        
    </html>
    

    实现 在用户登录的情况下显示注销,否则不显示

    【注意:authorize:授权 isAuthenticated():在springboot2.0.7版本以上不生效,是否已经认证(用户是否登录)

    ​ 需要导入 命名空间5版本才生效

       <!--登录注销-->
    <!--            未登录-->
                <div class="right menu">
                    <div sec:authorize="!isAuthenticated()">
                        <!--未登录-->
                        <a class="item" th:href="@{/toLogin}">
                            <i class="address card icon"></i> 登录
                        </a>
                    </div>
    <!--               已登录-->
                    <div sec:authorize="isAuthenticated()">
                       <h3>
                           用户名:<span sec:authentication="name"></span>
                           角色:<span sec:authentication="principal.authorities"></span>
                       </h3>
                        <a class="item" th:href="@{/logout}">
                            <i class="address card icon"></i> 注销
                        </a>
    
                    </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}"><i class="bullhorn icon"></i> Level-3-1</a></div>
                                <div><a th:href="@{/level3/2}"><i class="bullhorn icon"></i> Level-3-2</a></div>
                                <div><a th:href="@{/level3/3}"><i class="bullhorn icon"></i> Level-3-3</a></div>
                            </div>
                        </div>
                    </div>
    </div>
    

    定制登录页面

    //开启自动配置登录功能
    http.formLogin().usernameParameter("username").passwordParameter("password").loginPage("/toLogin");
    

    实现记住我功能

    //    开启记住我  功能
        http.rememberMe().rememberMeParameter("remeber");   //需要对应登录界面的CheckBox 的name值
    

    4.代码

    配置类:

    package com.king.security.config;
    
    import org.springframework.security.authentication.AuthenticationManager;
    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;
    
    @EnableWebSecurity
    public class MySecurityConfig extends WebSecurityConfigurerAdapter {
    
        //定义认证规则
        @Override
        protected void configure(AuthenticationManagerBuilder auth) throws Exception {
            auth.inMemoryAuthentication().passwordEncoder(new BCryptPasswordEncoder())
                    .withUser("zhangsan").password(new BCryptPasswordEncoder().encode("123456")).roles("VIP1","VIP2")
                    .and()
                    .withUser("lisi").password(new BCryptPasswordEncoder().encode("123456")).roles("VIP2","VIP3")
                    .and()
                    .withUser("wangwu").password(new BCryptPasswordEncoder().encode("123456")).roles("VIP1","VIP3");
        }
    
        @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");
            //1、/login请求来到登录页
            //2、重定向到/login?error 表示登录失败
            //3、更多功能
    
    
        //    开启自动配置的注销功能
            //防止网站攻击
            http.csrf().disable();
            http.logout().logoutSuccessUrl("/");
    
        //    开启记住我  功能
            http.rememberMe().rememberMeParameter("remeber");
        //    登录成功之后  将cookie发给浏览器保存,以后登录会带上这个cookie,只要通过验证就可以免登录访问页面
        //    点击注销会删除cookie
    
    
    
        }
    }
    
    

    controller:

    package com.king.security.controller;
    
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.PathVariable;
    import org.springframework.web.bind.annotation.RequestMapping;
    
    @Controller
    public class SecurityController {
    
        //首页
        @RequestMapping({"/", "/index.html","/index"})
        public String index(){
            return "index";
        }
        //登录页
        @RequestMapping("/toLogin")
        public String loginPage(){
            return "views/login";
        }
    
    //    页面映射
        @RequestMapping("/level1/{path}")
        public String level1(@PathVariable("path") String path){
            return "views/level1/"+path;
        }
    
        @RequestMapping("/level2/{path}")
        public String level2(@PathVariable("path") String path){
            return "views/level2/"+path;
        }
    
        @RequestMapping("/level3/{path}")
        public String level3(@PathVariable("path") String path){
            return "views/level3/"+path;
        }
    
    
    
    }
    
    

    首页:index.html

    <!DOCTYPE html>
    <html lang="en" xmlns:th="http://www.thymeleaf.org"
          xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity5">
    <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="stylesheet">
        <link th:href="@{/qinjiang/css/qinstyle.css}" 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="@{/}">首页</a>
    
    
                <!--登录注销-->
    <!--            未登录-->
                <div class="right menu">
                    <div sec:authorize="!isAuthenticated()">
                        <!--未登录-->
                        <a class="item" th:href="@{/toLogin}">
                            <i class="address card icon"></i> 登录
                        </a>
                    </div>
    <!--               已登录-->
                    <div sec:authorize="isAuthenticated()">
                       <h3>
                           用户名:<span sec:authentication="name"></span>
                           角色:<span sec:authentication="principal.authorities"></span>
                       </h3>
                        <a class="item" th:href="@{/logout}">
                            <i class="address card icon"></i> 注销
                        </a>
    
                    </div>
                </div>
            </div>
        </div>
    
        <div class="ui segment" style="text-align: center">
            <h3>Spring Security </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}"><i class="bullhorn icon"></i> Level-1-1</a></div>
                                <div><a th:href="@{/level1/2}"><i class="bullhorn icon"></i> Level-1-2</a></div>
                                <div><a th:href="@{/level1/3}"><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}"><i class="bullhorn icon"></i> Level-2-1</a></div>
                                <div><a th:href="@{/level2/2}"><i class="bullhorn icon"></i> Level-2-2</a></div>
                                <div><a th:href="@{/level2/3}"><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}"><i class="bullhorn icon"></i> Level-3-1</a></div>
                                <div><a th:href="@{/level3/2}"><i class="bullhorn icon"></i> Level-3-2</a></div>
                                <div><a th:href="@{/level3/3}"><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>
    

    登录页:

    <!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="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="@{/toLogin}" 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">
                                    <div class="checkbox">
                                        <label>
                                            <input type="checkbox" name="remeber" id="">记住我 <br>
                                        </label>
                                    </div>
                                </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></small>
            </div>
            <div class="ui segment" style="text-align: center">
                <h3></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>
    

    level1/1.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="stylesheet">
        <link th:href="@{/qinjiang/css/qinstyle.css}" rel="stylesheet">
    </head>
    <body>
    
    <!--主容器-->
    <div class="ui container">
    
        <div th:replace="~{index::nav-menu}"></div>
    
        <div class="ui segment" style="text-align: center">
            <h3>Level-1-1</h3>
        </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>
    
  • 相关阅读:
    P5107 能量采集
    P4655 [CEOI2017]Building Bridges
    P1129 [ZJOI2007]矩阵游戏
    P5299 [PKUWC2018]Slay the Spire
    P1625求和 giao精大杂烩
    背包
    根号分治
    CF963B
    国王游戏
    P6006 USACO 3SUM G
  • 原文地址:https://www.cnblogs.com/KingTL/p/13079899.html
Copyright © 2020-2023  润新知