Spring Security 核心过滤器链讲解

对于Spring Security,核心过滤器链可以说是它的核心之一。本文将从什么是核心过滤器链、以及它包含哪些过滤器等方面进行详细讲解。

1. 什么是核心过滤器链?

核心过滤器链是Spring Security运作的基础。当一个请求进来时,它将会被一系列的过滤器处理,处理完成后才会交给真正的应用程序处理。核心过滤器链由一系列的过滤器组成,每个过滤器都有自己的功能和责任。

2. 核心过滤器链包含哪些过滤器?

Spring Security的核心过滤器链由以下过滤器组成:

  1. ChannelProcessingFilter - 它主要负责检查请求是否是从安全渠道(HTTPS)发送来的。如果不是,则拒绝该请求或者将其重定向到HTTPS。

  2. SecurityContextPersistenceFilter - 它的主要作用是在HttpServletRequest中存储Spring Security的SecurityContext。SecurityContext存储了对当前用户的验证信息和授权信息。

  3. ConcurrentSessionFilter - 它负责并发会话控制。如果用户的会话已经被其他人占用,则它将防止用户使用该会话。当然,这个功能是可配置的。

  4. LogoutFilter - 它主要负责用户退出登录时的处理工作,比如清空session、删除cookie等。

  5. UsernamePasswordAuthenticationFilter - 它是用户认证的核心。它接收以POST方式提交的“username”和“password”,并将它们封装成一个UsernamePasswordAuthenticationToken传递给AuthenticationManager进行认证。

  6. DefaultLoginPageGeneratingFilter - 它负责生成默认的登录页面。该过滤器会从当前应用程序的登录页面生成表单,并将它们提供给用户进行登录。

  7. BasicAuthenticationFilter - 它可能是最简单的过滤器之一。它负责基本身份验证。它从HTTP头中提取用户名和密码,并将它们传递给AuthenticationManager进行认证。

  8. RequestCacheAwareFilter - 它负责将请求缓存起来,以便在用户重定向到登录页面后,将请求的原始URL存储在HttpSession中。

  9. SecurityContextHolderAwareRequestFilter - 它负责检查当前请求是否是SECURITY_CONTEXT_ATTRIBUTE设置为NONE的请求。如果是,它将使用SecurityContextHolder来清除安全上下文对象。

  10. AnonymousAuthenticationFilter - 它负责生成匿名Authentication对象,并将其传递给SecurityContextHolder。这个过滤器通常在用户未认证时使用。

  11. SessionManagementFilter - 它负责会话管理,比如会话超时的处理等。

  12. ExceptionTranslationFilter - 它负责在发生认证异常或授权异常时的处理工作。

  13. FilterSecurityInterceptor - 它负责处理URL级别的安全性。它从配置中检索所需的访问级别,并检查当前用户是否具有该访问级别。

3. 核心过滤器链示例

下面是两个基于Spring Security的简单web应用程序的例子:

示例1

  1. 实现类org.springframework.security.web.context.AbstractSecurityWebApplicationInitializer

```java
package com.example.config;

import org.springframework.security.web.context.AbstractSecurityWebApplicationInitializer;

public class SecurityWebApplicationInitializer extends AbstractSecurityWebApplicationInitializer {

}
```

  1. 配置类com.example.config.WebSecurityConfig

```java
package com.example.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
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.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.factory.PasswordEncoderFactories;
import org.springframework.security.crypto.password.PasswordEncoder;

configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

   @Autowired
   private UserDetailsService userDetailsService;

   @Override
   protected void configure(HttpSecurity http) throws Exception {
       http.authorizeRequests().anyRequest().authenticated().and().formLogin().and().httpBasic();
   }

   @Autowired
   public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
       PasswordEncoder passwordEncoder = PasswordEncoderFactories.createDelegatingPasswordEncoder();
       auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder);
   }

}
```

  1. 实现类com.example.config.MyUserDetailsService

```java
package com.example.config;

import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Component;

import java.util.Collections;

@Component
public class MyUserDetailsService implements UserDetailsService {

   private final PasswordEncoder encoder;

   public MyUserDetailsService() {
       this.encoder = PasswordEncoderFactories.createDelegatingPasswordEncoder();
   }

   @Override
   public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
       if (username.equals("admin")) {
           return User.withUsername("admin").password(encoder.encode("123456")).roles(Collections.singletonList("USER")).build();
       }
       throw new UsernameNotFoundException("User '" + username + "' not found");
   }

}
```

示例2

  1. 实现类org.springframework.security.web.context.AbstractSecurityWebApplicationInitializer

```java
package com.example.config;

import org.springframework.security.web.context.AbstractSecurityWebApplicationInitializer;

public class SecurityWebApplicationInitializer extends AbstractSecurityWebApplicationInitializer {

}
```

  1. 配置类com.example.config.WebSecurityConfig

```java
package com.example.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
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.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.factory.PasswordEncoderFactories;
import org.springframework.security.crypto.password.PasswordEncoder;

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

   @Autowired
   private UserDetailsService userDetailsService;

   @Override
   protected void configure(HttpSecurity http) throws Exception {
       http.authorizeRequests().antMatchers("/public/**").permitAll().anyRequest().authenticated().and().formLogin().and().httpBasic();
   }

   @Autowired
   public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
       PasswordEncoder passwordEncoder = PasswordEncoderFactories.createDelegatingPasswordEncoder();
       auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder);
   }

}
```

  1. 控制器类com.example.controller.PublicController

```java
package com.example.controller;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class PublicController {

   @GetMapping("/public")
   public String publicEndpoint() {
       return "Hello Public!";
   }

}
```

  1. 控制器类com.example.controller.SecureController

```java
package com.example.controller;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class SecureController {

   @GetMapping("/secure")
   public String secureEndpoint() {
       return "Hello Secure!";
   }

}
```

通过对两个示例的了解,我们可以初步认识Spring Security核心过滤器链的作用和用法。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Spring Security 核心过滤器链讲解 - Python技术站

(0)
上一篇 2023年5月20日
下一篇 2023年5月20日

相关文章

  • spring batch线上异常定位记录

    以下是关于Spring Batch线上异常定位记录的完整攻略: 1. 异常定位前的准备工作 在使用Spring Batch时,我们需要做好记录异常信息的工作,可以借助Spring Batch提供的日志输出功能进行记录。特别地,我们在实现任务的时候,可以添加定时异常上报的任务。这样,出现问题时我们可以迅速地了解问题所在,进行快速的定位。 2. 异常记录方式 2…

    Java 2023年5月27日
    00
  • Java数组队列及环形数组队列超详细讲解

    Java数组队列及环形数组队列超详细讲解 什么是队列 队列(Queue)是一种先进先出(FIFO, first in first out)的数据结构,常见的队列有数组队列和链式队列两种实现方式。 数组队列 数组队列是一种线性结构,底层使用静态数组来存储数据。队列的头部(front)指向队列头部元素,队列尾(rear)指向队列尾部元素。当有新元素入队时,队列尾…

    Java 2023年5月26日
    00
  • java如何实现抽取json文件指定字段值

    要实现抽取JSON文件指定字段值,可以通过使用Java中的JSON库和一些基本的数据结构来完成。以下是步骤和示例: 1. 导入JSON库 在Java程序中,最常见的JSON处理库是org.json。可以通过Maven来添加库的依赖,或者将JAR文件直接添加到项目的类路径中。以Maven为例,需要在pom.xml文件中添加以下代码: <dependenc…

    Java 2023年5月26日
    00
  • 一篇超详细的Spring Boot整合Mybatis文章

    Spring Boot整合MyBatis完整攻略 Spring Boot是一个快速开发框架,可以帮助开发人员快速构建Web应用程序。在Spring Boot中,整合MyBatis可以帮助我们更方便地操作数据库。本文将介绍如何在Spring Boot中整合MyBatis,并提供两个示例。 整合MyBatis 在Spring Boot中整合MyBatis需要以下…

    Java 2023年5月15日
    00
  • 详细讲解Java中的main()方法

    详细讲解Java中的main()方法 什么是main()方法 在Java中,每个可执行程序都必须包含一个名为 main 的方法。main 方法是程序的入口点,是Java程序启动时执行的第一个方法。在Java中,main 方法被定义为 public static void main(String[] args)。这表示 main 方法是公共的(可以从任何地方访…

    Java 2023年5月23日
    00
  • 微信怎么群发标签好友信息?微信群发标签好友教程

    微信怎么群发标签好友信息 在微信中,我们可以通过标签来分类好友。有了标签,我们就可以很方便地进行按标签进行群发操作。下面,我们来详细讲解如何在微信中群发标签好友信息的操作步骤。 第一步:创建标签 首先,我们需要在微信中创建好友标签,把需要进行群发操作的好友添加进标签中。具体操作步骤如下: 点击微信底部的“我”选项,进入个人主页。 点击“通讯录”选项进入好友列…

    Java 2023年6月15日
    00
  • Asp.net FileUpload+Image制作头像效果示例代码

    我们来详细讲解一下“ASP.NET FileUpload+Image制作头像效果示例代码”的完整攻略。 概述 首先,我们需要了解一些基本的概念。在 ASP.NET 中,我们可以使用 FileUpload 控件来接收用户上传的文件,使用 Image 控件来展示上传的图片。一般来说,用户上传头像时,我们需要对其进行剪裁、压缩等操作,以获得更好的用户体验。 第一步…

    Java 2023年5月19日
    00
  • Java的Struts框架报错“ObjectNotFoundException”的原因与解决办法

    当使用Java的Struts框架时,可能会遇到“ObjectNotFoundException”错误。这个错误通常由以下原因之一起: 对象不存在:如果请求的对象不存在,则可能会出现此错误。在这种情况下,需要检查对象是否存在以解决此问题。 配置错误:如果配置文件中没有正确配置,则可能会出现此错误。在这种情况下,需要检查文件以解决此问题。 以下是两个实例: 例 …

    Java 2023年5月5日
    00
合作推广
合作推广
分享本页
返回顶部