springSecurity安全

Security 原理分析

SpringSecurity 过滤器链
SpringSecurity 采用的是责任链的设计模式,它有一条很长的过滤器链。现在对这条过滤器链的各个进行说明:

pom文件

导入整合项目的依赖

<?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.0.9.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.kaung.w</groupId>
    <artifactId>spring-06-security</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>spring-06-security</name>
    <description>security 安保 for Spring Boot</description>
    <properties>
        <java.version>1.8</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <!--Thymeleaf依赖开始 当前默认版本3.0.12-->

        <dependency>
            <groupId>org.thymeleaf</groupId>
            <artifactId>thymeleaf-spring5</artifactId>
        </dependency>
        <dependency>
            <groupId>org.thymeleaf.extras</groupId>
            <artifactId>thymeleaf-extras-java8time</artifactId>
        </dependency>
        <!--     安全 security  -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
            <version>2.3.9.RELEASE</version>
        </dependency>
        <!-- thymeleaf-springSecurity 整合包 -->
        <dependency>
            <groupId>org.thymeleaf.extras</groupId>
            <artifactId>thymeleaf-extras-springsecurity4</artifactId>
            <version>3.0.4.RELEASE</version>
        </dependency>

    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

  • WebAsyncManagerIntegrationFilter:将 Security 上下文与 Spring Web 中用于处理异步请求映射的 WebAsyncManager 进行集成。

  • SecurityContextPersistenceFilter:在每次请求处理之前将该请求相关的安全上下文信息加载到 SecurityContextHolder 中,然后在该次请求处理完成之后,将 SecurityContextHolder 中关于这次请求的信息存储到一个“仓储”中,然后将 SecurityContextHolder 中的信息清除,例如在Session中维护一个用户的安全信息就是这个过滤器处理的。

  • HeaderWriterFilter:用于将头信息加入响应中。

  • CsrfFilter:用于处理跨站请求伪造。

  • LogoutFilter:用于处理退出登录。

  • UsernamePasswordAuthenticationFilter:用于处理基于表单的登录请求,从表单中获取用户名和密码。默认情况下处理来自 /login 的请求。从表单中获取用户名和密码时,默认使用的表单 name 值为 username 和 password,这两个值可以通过设置这个过滤器的usernameParameter 和 passwordParameter 两个参数的值进行修改。

  • DefaultLoginPageGeneratingFilter:如果没有配置登录页面,那系统初始化时就会配置这个过滤器,并且用于在需要进行登录时生成一个登录表单页面。

  • BasicAuthenticationFilter:检测和处理 http basic 认证。

  • RequestCacheAwareFilter:用来处理请求的缓存。

  • SecurityContextHolderAwareRequestFilter:主要是包装请求对象request。

  • AnonymousAuthenticationFilter:检测 SecurityContextHolder 中是否存在 Authentication 对象,如果不存在为其提供一个匿名 Authentication。

  • SessionManagementFilter:管理 session 的过滤器

  • ExceptionTranslationFilter:处理 AccessDeniedException 和 AuthenticationException 异常。

  • FilterSecurityInterceptor:可以看做过滤器链的出口。

  • RememberMeAuthenticationFilter:当用户没有登录而直接访问资源时, 从 cookie 里找出用户的信息, 如果 Spring Security 能够识别出用户提供的remember me cookie, 用户将不必填写用户名和密码, 而是直接登录进入系统,该过滤器默认不开启。

启用security的实体类

package com.kaung.w.config;


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;


/**
 * @ClassName : MySecurityConfig  //类名
 * @Description : security安全配置  //描述
 * @Author : W //作者
 * @Date: 2021/4/29  11:33
 * @EnableWebSecurity Aop拦截器
 */

@EnableWebSecurity
public class MySecurityConfig extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        System.out.println ("进入了MySecurityConfig方法!");
        /**责任链式编程
         * 首页所有人可以访问,功能页只 有对应有权限的人才能访问
         * 请求授权的规则
         * */

        http.authorizeRequests ()
                .antMatchers ("/").permitAll ()

                .antMatchers ("/level1/**").hasRole ("vip1")
                .antMatchers ("/level2/**").hasRole ("vip2")
                .antMatchers ("/level3/**").hasRole ("vip3");
        //开启登录的页面  没有权限默认会到登录页面,http.formLogin ()
//定制登录页 loginPage ("/toLogin");
        http.formLogin ().loginPage ("/toLogin");

        // 开启了注销功能
        //防止攻击 springBoot 默认开启了防止网站攻击
        //关闭 springboot默认配置
        http.csrf ().disable ();
        http.logout ().logoutSuccessUrl ("/");
//开启记住我 自定义记住我的name值
        http.rememberMe ().rememberMeParameter ("rememberMe");
    }

    /**
     * //认证,springboot 2.1.X可以直接使用
     * //密码编码: PasswordEncoder
     * //在Spring secutiry 5.0+ 新增了很多的加密方法
     */

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.inMemoryAuthentication ().passwordEncoder (new BCryptPasswordEncoder ())
                //这些数据正常应该从数据库中读
                .withUser ("ww").password (new BCryptPasswordEncoder ().encode ("123")).roles ("vip1", "vip2")
                .and ()
                .withUser ("root").password (new BCryptPasswordEncoder ().encode ("123")).roles ("vip1", "vip2", "vip3")
                .and ()
                .withUser ("guest").password (new BCryptPasswordEncoder ().encode ("123456")).roles ("vip2");
    }
}


RouterController 配置类

package com.kaung.w.controller;

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

/**
 * @ClassName : RouterController  //类名
 * @Description : 页面跳转的配置 controller层  //描述
 * @Author : W //作者
 * @Date: 2021/4/29  10:48
 */
@Controller
public class RouterController {

    @RequestMapping({"/", "/index"})
    public String index() {
        return "index";
    }

    @RequestMapping({"/toLogin"})
    public String toLogin() {
        return "views/login";
    }

    @RequestMapping({"/level1/{id}"})
    public String toLevel1(@PathVariable("id") int id) {
        return "views/level1/" + id;
    }

    @RequestMapping({"/level2/{id}"})
    public String toLevel2(@PathVariable("id") int id) {
        return "views/level2/" + id;
    }

    @RequestMapping({"/level3/{id}"})
    public String toLevel3(@PathVariable("id") int id) {
        return "views/level3/" + id;
    }
}

资源图示
springSecurity安全

上一篇:Starting MySQL...The server quit without updating PID file


下一篇:BZOJ1614:[USACO]Telephone Lines架设电话线(二分,最短路)