Java中的Spring Security配置过滤器

目录
  • AbstractAuthenticationFilterConfigurer
  • 改造过程
  • 配置类效果

前言:

CaptchaAuthenticationFilter是通过模仿UsernamePasswordAuthenticationFilter实现的。同样的道理,由于UsernamePasswordAuthenticationFilter的配置是由FormLoginConfigurer来完成的,应该也能模仿一下FormLoginConfigurer,写一个配置类CaptchaAuthenticationFilterConfigurer去配置CaptchaAuthenticationFilter

public final class FormLoginConfigurer<H extends HttpSecurityBuilder<H>> extends
		AbstractAuthenticationFilterConfigurer<H, FormLoginConfigurer<H>, UsernamePasswordAuthenticationFilter> {

    // 省略
}    

AbstractAuthenticationFilterConfigurer

FormLoginConfigurer看起来有点复杂,不过继承关系并不复杂,只继承了AbstractAuthenticationFilterConfigurer

public abstract class AbstractAuthenticationFilterConfigurer<B extends HttpSecurityBuilder<B>, T extends AbstractAuthenticationFilterConfigurer<B, T, F>, F extends AbstractAuthenticationProcessingFilter>
		extends AbstractHttpConfigurer<T, B> {
}    

理论上我们模仿一下,也继承一下这个类,但是你会发现这种方式行不通。因为AbstractAuthenticationFilterConfigurer只能Spring Security内部使用,不建议自定义。原因在于它最终向HttpSecurity添加过滤器使用的是HttpSecurity.addFilter(Filter)方法,这个方法只有内置过滤器(参见FilterOrderRegistration)才能使用。了解了这个机制之后,我们只能往上再抽象一层,去改造其父类AbstractHttpConfigurer

改造过程

AbstractAuthenticationFilterConfigurer<B,T,F>中的B是实际指的HttpSecurity,因此这个要保留;

T指的是它本身的实现,我们配置CaptchaAuthenticationFilter不需要下沉一层到FormLoginConfigurer这个继承级别,直接在AbstractAuthenticationFilterConfigurer这个继承级别实现即可,因此T这里指的就是需要配置类本身,也不需要再抽象化,因此是不需要的;同样的原因F也不需要,很明确是CaptchaAuthenticationFilter,不需要再泛化。这样CaptchaAuthenticationFilter的配置类结构可以这样定义:

public class CaptchaAuthenticationFilterConfigurer<H extends HttpSecurityBuilder<H>> extends AbstractHttpConfigurer<CaptchaAuthenticationFilterConfigurer<H>, H> {
    // 不再泛化  具体化
    private final CaptchaAuthenticationFilter authFilter;
    // 特定的验证码用户服务
    private CaptchaUserDetailsService captchaUserDetailsService;
    // 验证码处理服务
    private CaptchaService captchaService;
    // 保存认证请求细节的策略
    private AuthenticationDetailsSource<HttpServletRequest, ?> authenticationDetailsSource;
    // 默认使用保存请求认证成功处理器
    private SavedRequestAwareAuthenticationSuccessHandler defaultSuccessHandler = new SavedRequestAwareAuthenticationSuccessHandler();
    // 认证成功处理器
    private AuthenticationSuccessHandler successHandler = this.defaultSuccessHandler;
     // 登录认证端点
    private LoginUrlAuthenticationEntryPoint authenticationEntryPoint;
    // 是否 自定义页面
    private boolean customLoginPage;
    // 登录页面
    private String loginPage;
    // 登录成功url
    private String loginProcessingUrl;
    // 认证失败处理器
    private AuthenticationFailureHandler failureHandler;
    // 认证路径是否放开
    private boolean permitAll;
    //  认证失败的url
    private String failureUrl;

    /**
     * Creates a new instance with minimal defaults
     */
    public CaptchaAuthenticationFilterConfigurer() {
        setLoginPage("/login/captcha");
        this.authFilter = new CaptchaAuthenticationFilter();
    }
    public CaptchaAuthenticationFilterConfigurer<H> formLoginDisabled() {
        this.formLoginEnabled = false;
        return this;
    }
    public CaptchaAuthenticationFilterConfigurer<H> captchaUserDetailsService(CaptchaUserDetailsService captchaUserDetailsService) {
        this.captchaUserDetailsService = captchaUserDetailsService;
        return this;
    }
    public CaptchaAuthenticationFilterConfigurer<H> captchaService(CaptchaService captchaService) {
        this.captchaService = captchaService;
        return this;
    }
    public CaptchaAuthenticationFilterConfigurer<H> usernameParameter(String usernameParameter) {
        authFilter.setUsernameParameter(usernameParameter);
        return this;
    }
    public CaptchaAuthenticationFilterConfigurer<H> captchaParameter(String captchaParameter) {
        authFilter.setCaptchaParameter(captchaParameter);
        return this;
    }
    public CaptchaAuthenticationFilterConfigurer<H> parametersConverter(Converter<HttpServletRequest, CaptchaAuthenticationToken> converter) {
        authFilter.setConverter(converter);
        return this;
    }
    @Override
    public void init(H http) throws Exception {
        updateAuthenticationDefaults();
        updateAccessDefaults(http);
        registerDefaultAuthenticationEntryPoint(http);
        // 这里禁用默认页面过滤器 如果你想自定义登录页面 可以自行实现 可能和FormLogin冲突
        // initDefaultLoginFilter(http);
        // 把对应的Provider也在init时写入HttpSecurity
        initProvider(http);
    }
     @Override
    public void configure(H http) throws Exception {
        //这里改为使用前插过滤器方法
         http.addFilterBefore(filter, LogoutFilter.class);
    }
     // 其它方法 同AbstractAuthenticationFilterConfigurer
}  

其实就是模仿AbstractAuthenticationFilterConfigurer及其实现类的风格把用的配置项实现一边。这里值得一提的是CaptchaService的配置也可以从Spring IoC中查找(参考getBeanOrNull方法,这个方法在Spring Security中随处可见,建议借鉴),这样更加灵活,既能从方法配置也能自动注入。

    private void initProvider(H http) {
        ApplicationContext applicationContext = http.getSharedObject(ApplicationContext.class);
        // 没有配置CaptchaUserDetailsService就去Spring IoC获取
        if (captchaUserDetailsService == null) {
            captchaUserDetailsService = getBeanOrNull(applicationContext, CaptchaUserDetailsService.class);
        }
        // 没有配置CaptchaService就去Spring IoC获取
        if (captchaService == null) {
            captchaService = getBeanOrNull(applicationContext, CaptchaService.class);
        }
        // 初始化 Provider
        CaptchaAuthenticationProvider captchaAuthenticationProvider = this.postProcess(new CaptchaAuthenticationProvider(captchaUserDetailsService, captchaService));
        // 会增加到ProviderManager的注册列表中
        http.authenticationProvider(captchaAuthenticationProvider);
    }

配置类效果

我们来看看CaptchaAuthenticationFilterConfigurer的配置效果:

    @Bean
    SecurityFilterChain defaultSecurityFilterChain(HttpSecurity http, UserDetailsService userDetailsService) throws Exception {
        http.csrf().disable()
                .authorizeRequests()
                .mvcMatchers("/foo/**").access("hasAuthority('ROLE_USER')")
                .anyRequest().authenticated()
                .and()
                // 所有的 AbstractHttpConfigurer 都可以通过apply方法加入HttpSecurity
                .apply(new CaptchaAuthenticationFilterConfigurer<>())
                // 配置验证码处理服务   这里直接true 方便测试
                .captchaService((phone, rawCode) -> true)
                // 通过手机号去拿验证码,这里为了方便直接写死了,实际phone和username做个映射
                .captchaUserDetailsService(phone -> userDetailsService.loadUserByUsername("felord"))
                // 默认认证成功跳转到/路径  这里改造成把认证信息直接返回json
                .successHandler((request, response, authentication) -> {
                // 这里把认证信息以JSON形式返回
                    ServletServerHttpResponse servletServerHttpResponse = new ServletServerHttpResponse(response);
                    MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter = new MappingJackson2HttpMessageConverter();
                           mappingJackson2HttpMessageConverter.write(authentication, MediaType.APPLICATION_JSON,servletServerHttpResponse);
                });
        return http.build();
    }

是不是要优雅很多,解决了你自己配置过滤器的很多疑难杂症。学习一定要模仿,先模仿成功,然后再分析思考为什么会模仿成功,最后形成自己的创造力。千万不要被一些陌生概念唬住,有些改造是不需要去深入了解细节的。

到此这篇关于Java中的Spring Security配置滤器的文章就介绍到这了,更多相关Spring Security过滤器内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Java SpringSecurity入门案例与基本原理详解

    目录 1.入门案例 1.1.创建SpringBoot项目 1.2.勾选对应的maven依赖 1.3.编写Controller路由 1.4.启动项目 2.基本原理 2.1.Security的本质 2.2.Security装载过程(一) 2.3.Security装载过程(二) 2.4.UsernamePasswordAuthenticationFilter过滤器 总结 1.入门案例 1.1.创建SpringBoot项目 1.2.勾选对应的maven依赖 这里一些依赖可以没有,最主要是要有Web和Se

  • Spring Security拦截器引起Java CORS跨域失败的问题及解决

    在已设置CORS的项目中加入Spring Security,导致跨域访问失败,一开始以为是设置错CORS的问题,后来才发现是因为Spring Security的拦截冲突引起的. (一) CORS介绍 CORS是一个W3C标准,全称是"跨域资源共享"(Cross-origin resource sharing). 它允许浏览器向跨源服务器,发出XMLHttpRequest请求,从而克服了AJAX只能同源使用的限制. response响应头 响应头字段名称 作用 Access-Contro

  • Java SpringBoot安全框架整合Spring Security详解

    目录 1.工业级安全框架介绍 2.建议搭建Spring Security环境 2.1在pom.xml中添加相关依赖 2.2创建Handler类 2.3创建简单的html和配置相关thymeleaf的路径 2.4最后再加个启动类,那么我们的整合测试就完成勒 2.5成果展示 用户名默认user,密码则随机生成的这串数字 3.进阶版使用 3.1用户名和密码自定义 3.2在config包下创建Encoder 3.3赋予账号角色权限 总结 1.工业级安全框架介绍 Spring Security基于Spri

  • java中Spring Security的实例详解

    java中Spring Security的实例详解 spring security是一个多方面的安全认证框架,提供了基于JavaEE规范的完整的安全认证解决方案.并且可以很好与目前主流的认证框架(如CAS,中央授权系统)集成.使用spring security的初衷是解决不同用户登录不同应用程序的权限问题,说到权限包括两部分:认证和授权.认证是告诉系统你是谁,授权是指知道你是谁后是否有权限访问系统(授权后一般会在服务端创建一个token,之后用这个token进行后续行为的交互). spring

  • java编程SpringSecurity入门原理及应用简介

    目录 1. SpringSecurity 框架简介 1.1 概要 1.2 组成以及同款产品(shiro)对比 1.2.1 Spring Security 1.2.2 Shiro 1.3 模块划分 1.4 SpringSecurity 基本原理 1.5.UserDetailsService 接口讲解 2.SpringSecurity Web 权限方案 2.1设置登录系统的账号密码(三种方式) 设计数据库表 建立springboot项目,勾选相应依赖 完整pom.xml 数据库配置 创建对应的实体类

  • Java Spring Security认证与授权及注销和权限控制篇综合解析

    Spring Security简介: Spring Security 是针对Spring项目的安全框架,也是Spring Boot底层安全模块默认的技术选型,它可以实现强大的Web安全控制,对于安全控制,我们只需要引入 spring-boot-starter-security 模块,进行少量的配置,即可实现强大的安全管理! 记住几个类: WebSecurityConfigurerAdapter:自定义Security策略 AuthenticationManagerBuilder:自定义认证策略

  • Java中的Spring Security配置过滤器

    目录 AbstractAuthenticationFilterConfigurer 改造过程 配置类效果 前言: CaptchaAuthenticationFilter是通过模仿UsernamePasswordAuthenticationFilter实现的.同样的道理,由于UsernamePasswordAuthenticationFilter的配置是由FormLoginConfigurer来完成的,应该也能模仿一下FormLoginConfigurer,写一个配置类CaptchaAuthent

  • java中自定义Spring Security权限控制管理示例(实战篇)

    背景描述 项目中需要做细粒的权限控制,细微至url + httpmethod (满足restful,例如: https://.../xxx/users/1, 某些角色只能查看(HTTP GET), 而无权进行增改删(POST, PUT, DELETE)). 表设计 为避嫌,只列出要用到的关键字段,其余敬请自行脑补. 1.admin_user 管理员用户表, 关键字段( id, role_id ). 2.t_role 角色表, 关键字段( id, privilege_id ). 3.t_privi

  • Spring security 自定义过滤器实现Json参数传递并兼容表单参数(实例代码)

    依赖 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId&g

  • Spring Security配置多个数据源并添加登录验证码的实例代码

    目录 1.配置多个数据源 2. 添加登录验证码 1.配置多个数据源 多个数据源是指在同一个系统中,用户数据来自不同的表,在认证时,如果第一张表没有查找到用户,那就去第二张表中査询,依次类推. 看了前面的分析,要实现这个需求就很容易了,认证要经过AuthenticationProvider,每一 个 AuthenticationProvider 中都配置了一个 UserDetailsService,而不同的 UserDetailsService 则可以代表不同的数据源,所以我们只需要手动配置多个A

  • Java开发之spring security实现基于MongoDB的认证功能

    本文实例讲述了Java开发之spring security实现基于MongoDB的认证功能.分享给大家供大家参考,具体如下: spring security对基于数据库的认证支持仅限于JDBC,而很多项目并非使用JDBC,比如Nosql数据库很多使用的是 Mongo Java Driver,这样就无法用默认的<jdbc-user-service>进行支持认证. 如果项目不是使用JDBC,没么解决办法就是:自己定义一个认证服务. 新建一个CustomUserDetailsService类 这个类

  • Spring Boot配置过滤器的2种方式示例

    前言 过滤器(Filter)是Servlet中常用的技术,可以实现用户在访问某个目标资源之前,对访问的请求和响应进行拦截,常用的场景有登录校验.权限控制.敏感词过滤等,下面介绍下Spring Boot配置过滤器的两种方式. 一.@WebFilter注解方式 使用@WebFilter注解为声明当前类为filter,第一个参数为该filter起一个名字,第二个参数为说明要拦截的请求地址,当前类需要实现Filter接口,里面有三个方法,分别为过滤器初始化.过滤方法和过滤器销毁. @Slf4j @Web

  • Spring Security常用过滤器实例解析

    Spring Security常见的15个拦截器 1 . org.springframework.security.web.context.SecurityContextPersistenceFilter 首当其冲的一个过滤器,作用之重要,自不必多言. SecurityContextPersistenceFilter主要是使用SecurityContextRepository在session中保存或更新一个 SecurityContext,并将SecurityContext给以后的过滤器使用,来

  • Spring Security基于过滤器实现图形验证码功能

    目录 前言 一. 验证码简介 二. 基于过滤器实现图形验证码 1. 实现概述 2. 创建新模块 3. 添加依赖包 4. 创建Producer对象 5. 创建生成验证码的接口 6. 自定义异常 7. 创建拦截验证码的过滤器 8. 编写SecurityConfig 9. 编写测试页面 10. 代码结构 11. 启动项目测试 前言 在前两个章节中,一一哥 带大家学习了Spring Security内部关于认证授权的核心API,以及认证授权的执行流程和底层原理.掌握了这些之后,对于Spring Secu

  • Spring Security的过滤器链机制

    目录 前言 请求执行链路 推荐阅读 前言 在“码农小胖哥”的文章中提到一个关键的过滤器链SecurityFilterChain,当一个请求 HttpServletRequest 进入 SecurityFilterChain 时,会通过 matches 方法来确定是否满足条件进入过滤器链,进而决定请求应该执行哪些过滤器.下面我们自己来梳理一遍. 请求执行链路 我们以之前的文章为例,使用@Configuration配置了一个SecurityFilterChain Bean,能在Spring Boot

  • SpringBoot浅析安全管理之Spring Security配置

    目录 Spring Security 的基本配置 基本用法 1. 创建项目添加依赖 2. 添加 hello 接口 3. 启动项目测试 配置用户名和密码 基于内存的认证 HttpSecurity 登录表单详细配置 注销登录配置 多个 HttpSecurity 密码加密 1. 为什么要加密 2. 加密方案 3. 实践 方法安全 在 Java 开发领域常见的安全框架有 Shiro 和 Spring Security.Shiro 是一个轻量级的安全管理框架,提供了认证.授权.会话管理.密码管理.缓存管理

随机推荐