SpringCloud Gateway Spring Security Webfluxを統合するキー(痛み解析)、およびサンプルアイテム


最近、会社のプロジェクトはバックエンドの認証、授権が必要で、会社のプロジェクトは現在SpringCloud Gatewayに基づいているので、いずれも1社の製品だと思ってSpring Securityを使うことにしました.
しかし、統合の過程で、いろいろな苦難を経験したので、最終的な統合の鍵を列挙して、必要な読者が二度とぶつからないようにしました.の
ネット上にもSpringCloudとSpring Securityの統合に基づく案がありますが、肝心なのはうちの会社のプロジェクトがGatewayを使っていることですので、ネット上の既存の案とは違います(ネット上ではzulを使っていることが多い)!既存のシナリオは、純粋なWebFluxではなく、Spring Securityの従来のSpringMVC(servlet)統合シナリオを使用しています.SpringCloud GatewayはwebFluxベースで、SpringMVCの伝統的な方法とは互換性がありません.例えば、HttpService Request、HttpService Response、HttpSessionは使用できません.WebFluxでは、Server WebExchangeとWebSessionが使用されます.違いは非常に大きく、興味のある自己検索WebFluxと反応式プログラミングです.
そこで、ネット上の従来の統合案に従って、まず1版を統合し、@EnableWebSecurityによってSpring Securityを構成し、コア構成クラスは以下の通りである.
package com.daybreak.config;

import com.daybreak.component_security.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
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.web.access.channel.ChannelProcessingFilter;

/**
 * SpringSecurity    
 */
@Configuration
@EnableWebSecurity
public class SpringSecurityConfig extends WebSecurityConfigurerAdapter {
    //security      url  
    private static final String[] excludedAuthPages = {
            "/auth/login",
            "/auth/logout",
            "/health",
            "/api/socket/**",
            "/**/*.ico"
    };

    //         JSON      (  httpBasic       )
    @Autowired
    private NotLoginHandler notLoginHandler;

    //         
    @Autowired
    private LoginValidateProvider loginValidateProvider;

    //              
    @Autowired
    private LoginSuccessHandler loginSuccessHandler;

    //              
    @Autowired
    private LoginFailedHandler loginFailedHandler;

    //                。      ,    403  
    @Autowired
    private MyAccessDeniedHandler myAccessDeniedHandler;

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        //    
        http
            .httpBasic()//  HTTP      
            .authenticationEntryPoint(notLoginHandler)//         JSON      (  httpBasic       )
            .and()
            .authorizeRequests()
            .antMatchers(excludedAuthPages).permitAll()  //             
            .antMatchers(HttpMethod.OPTIONS).permitAll() //option       
            .anyRequest().authenticated()//         
            .anyRequest().access("@rbacService.hasPermission(request,authentication)")//     ,            
            .and()
            .exceptionHandling().accessDeniedHandler(myAccessDeniedHandler)//            
            .and()
            .formLogin() //    
            .usernameParameter("username") //             
            .passwordParameter("password") //            
            .loginProcessingUrl("/auth/login") //          url
            .loginPage("http://127.0.0.1:8848/spring_security_pages/login.html")//httpBasic     ,        
            .successHandler(loginSuccessHandler)//       
            .failureHandler(loginFailedHandler)//       
            .permitAll();//              

        //  csrf      
        http.csrf().disable();
        //    ,         corsConfigurationSource()
        http.cors();
        http.addFilterBefore(new WebSecurityCorsFilter(), ChannelProcessingFilter.class);

        System.out.println("    !");
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        //             
        auth.authenticationProvider(loginValidateProvider);
    }
}

上記のコードに必要な「カスタム認証」、「カスタム認証」、「ログイン成功、失敗」などの注入コンポーネントは、ネット上で関連コードを見つけることができますが、これは言うまでもありません.
しかし、それは役に立たないことに注意してください.このような方法で統合しないでください.
コンパイルは正常で、実行はエラーがありませんが、機能しません.
様々な頭破血流の調査(ソースコードのデバッグ、研究、海外サイトでの資料の検索)を経て、ついに根本的な原因が発見された.
そこで、いろいろな資料(国内、国外の資料はほとんどない)を調べ、Spring Securityのソースコードを研究し続けたことで、やっと正しい統合方法が見つかった.すなわち、WebFluxをすべて使う方式で、メイン構成は@EnableWebFluxSecurityである.
成功したシナリオ!!!Spring Securityのプライマリプロファイルは次のとおりです.
package com.daybreak.xian.gateway.config_security_webflux;

import com.daybreak.xian.gateway.component_security_webflux.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.http.HttpMethod;
import org.springframework.security.config.annotation.web.reactive.EnableWebFluxSecurity;
import org.springframework.security.config.web.server.ServerHttpSecurity;
import org.springframework.security.web.server.SecurityWebFilterChain;

//       !
@EnableWebFluxSecurity
public class SecurityWebFluxConfig {
    //        ,               
    @Autowired
    private MyRBACServiceWebFlux myRBACServiceWebFlux;

    //                。      ,    403  
    @Autowired
    private MyAccessDeniedHandlerWebFlux myAccessDeniedHandlerWebFlux;

    //              
    @Autowired
    private LoginSuccessHandlerWebFlux loginSuccessHandlerWebFlux;

    //              
    @Autowired
    private LoginFailedHandlerWebFlux loginFailedHandlerWebFlux;

    //              
    @Autowired
    private LogoutSuccessHandlerWebFlux logoutSuccessHandlerWebFlux;

    //            ,      ,           
    @Autowired
    private CustomHttpBasicServerAuthenticationEntryPointWebFlux customHttpBasicServerAuthenticationEntryPoint;

    //security       
    private static final String[] excludedAuthPages = {
            "/auth/login",
            "/auth/logout",
            "/health",
            "/api/socket/**"
    };

    @Bean
    SecurityWebFilterChain webFluxSecurityFilterChain(ServerHttpSecurity http) throws Exception {
        http
//                .authenticationManager(myReactiveAuthenticationManager)//       。      ,      
                .authorizeExchange()
                .pathMatchers(excludedAuthPages).permitAll()  //             
                .pathMatchers(HttpMethod.OPTIONS).permitAll() //option       
                .and()
                .authorizeExchange().pathMatchers("/**").access(myRBACServiceWebFlux)//        ,               
                .anyExchange().authenticated()
                .and()
                .httpBasic()
                .and()
                .formLogin()
                .loginPage("/auth/login")//        
                .authenticationSuccessHandler(loginSuccessHandlerWebFlux) //    
                .authenticationFailureHandler(loginFailedHandlerWebFlux) //      
                .and().exceptionHandling().authenticationEntryPoint(customHttpBasicServerAuthenticationEntryPoint)  //            ,      ,           
                .and().exceptionHandling().accessDeniedHandler(myAccessDeniedHandlerWebFlux)//            
                .and() .csrf().disable()//      
                .logout().logoutUrl("/auth/logout")
                .logoutSuccessHandler(logoutSuccessHandlerWebFlux);//              

        return http.build();
    }
}

最初の失敗した統合方式に対応して、上のコードに必要な「カスタム認証」、「カスタム認証」、「ログイン成功、失敗」などの注入されたコンポーネントは、すべてWebFluxバージョンに対応する各種Handlerに変更されます.詳細はここでも説明しません.
同じように必要な友达に助けてほしい!
 
更新:同志达が私のこの文章に対する肯定に感谢して、多くの友达はすべてソースコードを望んで、私は最近ずっと忙しくて、その上コードは家の机の上でどこに置いてずっと探し当てていません.それから今日时间を割いて全体のハードディスクを検索して、ついに探し当てました..
プロジェクトはCSDNのリソースダウンロードに入れます.
プロジェクトのreadmeを貼り付けます.
#     :
1.    SpringCloud Gateway      ,   SpringSecurity,      Redis          。
2.  Gateway     Webflux  ,     Spring       、            SpringSecurity。
3.  ,     WebFlux   ,     ,          。
4.             ,            。    HBuilderX        。
5.    IDEA2018        。

# 1.    
1.   mysql8,      utf8mb4。
2.   redis   。

# 2.    
1.         “    ”  ,         (      redis)。
2.          “login.html” ,  “    ”  ,       ip  。

# 3.    
1.   sql   gateway   src/main/resources/db_files/spring_gateway_security.sql,   mysql8 ,   utf8mb4。
2.     src/main/resources/pages ,          HBuilderX         !

# 4.     
1.  eureka  -        
2.  gateway    (  、              )
3.  base-core    (          )
4.           login.html,          ,            。    、         。

# 5.      
1.gateway:src/main/java/com/daybreak/xian/gateway/config_security_webflux/:
      SpringBoot、SpringSecurity   ,SpringSecurity             “SecurityWebFluxConfig”。
2.gateway:src/main/java/com/daybreak/xian/gateway/component_security_webflux/:
      SpringSecurity WebFlux                 ,      、    、    、          。
3.gateway:src/main/java/com/daybreak/xian/gateway/controller/:
     “BusinessController”     ,                ,        。
4.base-core:src/main/java/com/daybreak/xian/basecore/controler/:
     “BusinessController”      ,             ,         ,        。

プロジェクトリソースアドレス:https://download.csdn.net/download/tiancao222/12658507