WebFluxSecurity6添加自定义登录过滤器

本文介绍了如何在SpringBoot应用中配置WebFlux安全、RSocket安全以及API路径权限控制,包括缓存、CSRF、跨域、注销等功能的实现。
摘要由CSDN通过智能技术生成
package com.kongjs.admin.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.rsocket.server.RSocketServerCustomizer;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.security.config.annotation.rsocket.EnableRSocketSecurity;
import org.springframework.security.config.annotation.web.reactive.EnableWebFluxSecurity;
import org.springframework.security.config.web.server.SecurityWebFiltersOrder;
import org.springframework.security.config.web.server.ServerHttpSecurity;
import org.springframework.security.core.userdetails.MapReactiveUserDetailsService;
import org.springframework.security.core.userdetails.ReactiveUserDetailsService;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.rsocket.core.SecuritySocketAcceptorInterceptor;
import org.springframework.security.web.server.SecurityWebFilterChain;
import org.springframework.security.web.server.authentication.*;
import org.springframework.security.web.server.authentication.logout.DelegatingServerLogoutHandler;
import org.springframework.security.web.server.authentication.logout.HeaderWriterServerLogoutHandler;
import org.springframework.security.web.server.authentication.logout.SecurityContextServerLogoutHandler;
import org.springframework.security.web.server.authentication.logout.WebSessionServerLogoutHandler;
import org.springframework.security.web.server.authorization.HttpStatusServerAccessDeniedHandler;
import org.springframework.security.web.server.context.NoOpServerSecurityContextRepository;
import org.springframework.security.web.server.csrf.CookieServerCsrfTokenRepository;
import org.springframework.security.web.server.csrf.XorServerCsrfTokenRequestAttributeHandler;
import org.springframework.security.web.server.header.ClearSiteDataServerHttpHeadersWriter;
import org.springframework.security.web.server.util.matcher.PathPatternParserServerWebExchangeMatcher;
import org.springframework.security.web.server.util.matcher.ServerWebExchangeMatchers;
import org.springframework.session.data.redis.config.annotation.web.server.EnableRedisWebSession;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.reactive.CorsConfigurationSource;
import org.springframework.web.cors.reactive.UrlBasedCorsConfigurationSource;

import java.util.Arrays;
import java.util.List;

@EnableCaching
@EnableWebFluxSecurity
@EnableRSocketSecurity
@EnableRedisWebSession
@Configuration
public class WebSecurityConfig {
    @Autowired
    private CacheManager cacheManager;

    @Bean
    public MapReactiveUserDetailsService userDetailsService() {
        UserDetails user = User.withDefaultPasswordEncoder().username("user").password("user").roles("USER").build();
        return new MapReactiveUserDetailsService(user);
    }

    private void addFilter(ServerHttpSecurity httpSecurity, ReactiveUserDetailsService userDetailsService) {
        ReactivePreAuthenticatedAuthenticationManager authenticationManager = new ReactivePreAuthenticatedAuthenticationManager(userDetailsService);
        ServerAuthenticationSuccessHandler authenticationSuccessHandler = new RedirectServerAuthenticationSuccessHandler("/");
        ServerAuthenticationFailureHandler authenticationFailureHandler = new RedirectServerAuthenticationFailureHandler("/");
        AuthenticationWebFilter authenticationFilter = new AuthenticationWebFilter(authenticationManager);
        authenticationFilter.setRequiresAuthenticationMatcher(ServerWebExchangeMatchers.pathMatchers(HttpMethod.POST, "/login"));
        authenticationFilter.setAuthenticationFailureHandler(authenticationFailureHandler);
        authenticationFilter.setServerAuthenticationConverter(new LoginAuthenticationConverter());
        authenticationFilter.setAuthenticationSuccessHandler(authenticationSuccessHandler);
        authenticationFilter.setSecurityContextRepository(NoOpServerSecurityContextRepository.getInstance());
        httpSecurity.addFilterAt(authenticationFilter, SecurityWebFiltersOrder.FORM_LOGIN);
        httpSecurity.exceptionHandling(exceptionHandling -> exceptionHandling.authenticationEntryPoint(new RedirectServerAuthenticationEntryPoint("/login")).accessDeniedHandler(new HttpStatusServerAccessDeniedHandler(HttpStatus.UNAUTHORIZED)));
    }

    private void authorize(ServerHttpSecurity httpSecurity) {
        httpSecurity.authorizeExchange(exchanges -> exchanges.pathMatchers("/login").permitAll().anyExchange().authenticated());
    }

    private void login(ServerHttpSecurity httpSecurity) {
        httpSecurity.httpBasic(ServerHttpSecurity.HttpBasicSpec::disable).formLogin(ServerHttpSecurity.FormLoginSpec::disable);
    }

    private void logout(ServerHttpSecurity httpSecurity) {
        DelegatingServerLogoutHandler logoutHandler = new DelegatingServerLogoutHandler(new SecurityContextServerLogoutHandler(), new WebSessionServerLogoutHandler(), new HeaderWriterServerLogoutHandler(new ClearSiteDataServerHttpHeadersWriter(ClearSiteDataServerHttpHeadersWriter.Directive.ALL)));
        httpSecurity.logout((logout) -> logout.logoutHandler(logoutHandler));
    }

    private void cors(ServerHttpSecurity httpSecurity) {
        httpSecurity.cors(ServerHttpSecurity.CorsSpec::disable);
    }

    private void csrf(ServerHttpSecurity httpSecurity) {
        httpSecurity.csrf(csrf -> csrf.csrfTokenRepository(new CookieServerCsrfTokenRepository()).csrfTokenRequestHandler(new XorServerCsrfTokenRequestAttributeHandler()));
    }

    private void requestCache(ServerHttpSecurity httpSecurity) {
        httpSecurity.requestCache(ServerHttpSecurity.RequestCacheSpec::disable);
    }

    private void securityContextRepository(ServerHttpSecurity httpSecurity) {
        httpSecurity.securityContextRepository(NoOpServerSecurityContextRepository.getInstance());
    }


    @Bean
    public CorsConfigurationSource corsConfigurationSource() {
        CorsConfiguration configuration = new CorsConfiguration();
        configuration.setAllowedOrigins(List.of("https://example.com"));
        configuration.setAllowedMethods(Arrays.asList("GET", "POST"));
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", configuration);
        return source;
    }


    @Order(Ordered.HIGHEST_PRECEDENCE)
    @Bean
    public SecurityWebFilterChain apiHttpSecurity(ServerHttpSecurity http) {
        http.securityMatcher(new PathPatternParserServerWebExchangeMatcher("/api/**")).authorizeExchange((exchanges) -> exchanges.anyExchange().authenticated());
        return http.build();
    }

    @Bean
    public SecurityWebFilterChain securityWebFilterChain(ServerHttpSecurity httpSecurity, ReactiveUserDetailsService userDetailsService) throws Exception {
        authorize(httpSecurity);
        login(httpSecurity);
        logout(httpSecurity);
        cors(httpSecurity);
        csrf(httpSecurity);
        requestCache(httpSecurity);
        securityContextRepository(httpSecurity);
        addFilter(httpSecurity, userDetailsService);
        return httpSecurity.build();
    }

    @Bean
    public RSocketServerCustomizer springSecurityRSocketSecurity(SecuritySocketAcceptorInterceptor interceptor) {
        return (server) -> server.interceptors((registry) -> registry.forSocketAcceptor(interceptor));
    }
}

  • 5
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
引用中的代码片段展示了一个使用WebFlux SecuritySecurityConfig类。而引用中的代码片段则展示了一个使用Spring Security的configure方法来配置AuthenticationManagerBuilder。引用则对Spring Security进行了简要介绍。 问题: 将WebFlux Security改为Web Security。 回答: 如果要将WebFlux Security改为Web Security,可以按照以下步骤进行修改: 1. 首先,在Spring Security的配置类上修改注解为@EnableWebSecurity。 2. 然后,将SecurityConfig类中的@EnableWebFluxSecurity注解移除。 3. 接着,将SecurityConfig类中的ReactiveAuthenticationManager改为AuthenticationManager,并将@Bean注解中的返回类型修改为AuthenticationManager。 4. 最后,根据需要进行其他必要的修改,例如修改WebSecurityConfigurerAdapter的configure方法。 请注意,以上只是修改的基本步骤,具体的细节可能会因为具体的需求而有所不同。因此,在进行修改之前,建议参考官方文档或相关资源,以确保正确配置和适应你的项目需求。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [SpringSecurity - WebFlux环境下实现用户动态认证](https://blog.csdn.net/qq_43692950/article/details/122508425)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 33.333333333333336%"] - *2* [解决security报错 - There is no PasswordEncoder mapped for the id “null](https://blog.csdn.net/PleaseBeStrong/article/details/130997490)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 33.333333333333336%"] - *3* [SpringBoot WebFlux集成WebFluxSecurity登录权限验证](https://blog.csdn.net/jilo88/article/details/120026353)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 33.333333333333336%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值