0

開発モードで実行しているとき、私のReactフロントエンド(React Routerで実行中)のログインページにリダイレクトするSpring Securityの設定に問題があります。私は、リダイレクトがフロントエンドで取り上げられていないと考えています。サーバー側のルーティングがSPAルーティングとどのように相互作用するかについての知識があります。SPAのReact Routerを使用したSpring Securityログインページのリダイレクト

私の開発フロントエンドWebサーバー(Facebook Create React Appを使用しています)は、localhost:3000、私のバックエンドのSpring Boot Tomcat on localhost:8080で実行されています。私はSpring Securityを有効にしました。これはTomcatサーバー(8080番ポート)上でうまく動作します。 localhost:8080がlocalhost:8080/loginに転送されます。 localhost:3000にアクセスすると、クロスオリジンエラーが発生するため、hereと記載されているように、SpringでCORSサポートが追加されました。私はまた、this春のブログ記事に相談しました。それは、もはやクロスオリジンエラーを取得しないという点で、うまくいくようです。ログインしていないながら、しかし、ローカルホストからの要求:ローカルホストの3000:8080 /ログインは次の値を返します。

HTTP/1.1 200 OK 
X-Powered-By: Express 
Accept-Ranges: bytes 
Access-Control-Allow-Origin: * 
Content-Type: text/html; charset=UTF-8 
Content-Length: 1496 
ETag: W/"5d8-80rXYG+kNfQ/xEJ7J2f1PA" 
Vary: Accept-Encoding 
Date: Tue, 10 Jan 2017 12:04:07 GMT 
Connection: keep-alive 

<!DOCTYPE html> 
... 

これは私のフロントエンドWebサーバにホストされたindex.htmlにあります。これは良いですが、私はlocalhost:3000/loginに転送する必要があり、ログインページをindex.htmlにレンダリングします。 >HttpSecurity.loginPage("/login")(春) - - >registry.addViewController("/login").setViewName("forward:/index.html")(春) -

私はそれがあるため、ルーティング設定の/ログインに転送していないと信じて、それはlocalhost:3000/から行く><Route path="/" component={ForwardToLandingPage} />(ルータに反応)

それは、うまくいきません終わり。私は、Tomcatサーバーがフロントエンドを3000/loginにリダイレクトするようにしたいが、フロントエンドはコンポーネントに行く。サーバ側のリダイレクトとフロントエンドのリアクションルータが適切な場所に移動する間に問題が発生しているようです。これがセットアップするには複雑すぎる場合は、このSpring Security全体を私の開発環境に置いてください。ここで

は私の設定です:

を設定

ReactDOM.render((
    <Router history={browserHistory}> 
     <Route path="/" component={ForwardToLandingPage} /> 
     <Route path="/login" component={Login} /> 
    </Router> 
    ), 
    document.getElementById('root') 
); 

Spring MVCの設定

@Configuration 
public class MvcConfig extends WebMvcConfigurerAdapter { 

    @Override 
    public void addViewControllers(ViewControllerRegistry registry) {   
     // This forwarding is required, as my React app is rendering on a div 
     // element with the ID 'root' in /index.html. But is this part of the 
     // problem? 
     registry.addViewController("/").setViewName("forward:/index.html"); 
     registry.addViewController("/login").setViewName("forward:/index.html"); 
    } 
} 

春CORS設定

をルーティングリアクト
@Configuration 
public class MyConfiguration { 

    @Bean 
    public FilterRegistrationBean corsFilter() { 
     UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); 
     CorsConfiguration config = new CorsConfiguration(); 
     config.setAllowCredentials(true); 
     config.addAllowedOrigin("http://localhost:3000"); 
     config.addAllowedHeader("*"); 
     config.addAllowedMethod("*"); 
     source.registerCorsConfiguration("/**", config); 
     FilterRegistrationBean bean = new FilterRegistrationBean(new CorsFilter(source)); 
     bean.setOrder(0); 
     return bean; 
    } 
} 

春のセキュリティ設定

@EnableWebSecurity 
public class SecurityConfig extends WebSecurityConfigurerAdapter { 

    @Override 
    protected void configure(HttpSecurity http) throws Exception { 
     http 
       .csrf().disable() // temporary fix 
       .authorizeRequests() 
        .antMatchers("/h2-console", "/public/**", "/static/**").permitAll() 
        .anyRequest().authenticated() 
        .and() 
       .formLogin() 
        .loginPage("/login") 
        .permitAll() 
        .and() 
       .logout() 
        .logoutRequestMatcher(new AntPathRequestMatcher("/logout")); 
    } 
} 

間違って何が起こっているの任意のアイデア?

問題の解決策にTomcatが関与するかどうかは疑問だったので、thisもチェックしました。

ありがとうございました! :)

+0

Facebook Create React Appへのリンクを投稿できますか、ajaxリクエストか通常のhttpリクエストですか? –

+0

'localhost:8080/login'はログインページですか? – chaoluo

+0

ご質問ありがとうございます。私は今日もっと実験してきましたが、私はバックエンドとフロントエンドの間のルーティングとリダイレクションに問題があると考えています。私は私の調査結果と設定で質問を更新しました。また、私は自分の開発環境にいるときに問題があると付け加えるべきです。ポート8080またはホストされているAWS Elastic Beanstalkにまっすぐ進むと、すべての(フロントエンドを含む)コンテンツがうまく動作します。それが修正するには複雑すぎる場合、私は開発環境でログインを無効にするだけです。 – Jannik

答えて

-1

私は古いバージョンのSpringセキュリティを使用していますが、CORSをサポートしているかどうかはわかりません。私は6年間、春のセキュリティを使用しているので、私は普通のフィルタを作成しました:それは、フィルタチェーン内の最初のフィルタになるように、

public class CORSFilter implements Filter { 

    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException { 
     HttpServletResponse response = (HttpServletResponse) res; 
     HttpServletRequest httpServletRequest = (HttpServletRequest) req; 
     // The headers needs to be on all responses. 
     String origin = httpServletRequest.getHeader("origin"); 
     if (origin == null) { 
      // Make the developers life simpler. The browser adds the origin but it is a pain to 
      // for developers to add this header while testing. 
      origin = "*"; 
     } 
     response.setHeader("Access-Control-Allow-Origin", origin.replace("\n", "")); 

     response.setHeader("Access-Control-Allow-Methods", "POST, GET, PUT, DELETE, OPTIONS"); 
     response.setHeader("Access-Control-Max-Age", "3600"); 
     response.setHeader("Access-Control-Allow-Credentials", "true"); 
     response.setHeader("Access-Control-Allow-Headers", "X-Requested-With, Content-Type, Accept, Authorization"); 

     // For options requests return immediately. Options does not require authentication so we want to return 
     // here to avoid all yet unknown security risks. 
     if (HttpMethod.OPTIONS.toString().equals(httpServletRequest.getMethod())) { 
      return; 
     } 
     chain.doFilter(req, res); 
    } 

    public void init(FilterConfig filterConfig) { 
    } 

    public void destroy() { 
    } 
} 

をそしてChannelProcessingFilter前に追加しました。

http.addFilterBefore(new CORSFilter(), ChannelProcessingFilter.class); 
http.formLogin()..... 
// all the other matchers and 

これがうまくいかない場合は、それがCORSの問題であるかどうかはわかりません。

+1

このクラウスに感謝します。 :)私のCORSフィルタのように、ちょうどそれを追加しました。私はCORSが何とかログインページへのリダイレクトを破っていると思った。私は今問題がルーティングとリダイレクトだけであると判断しました。CORSはうまく機能しています。 – Jannik

関連する問題