5

私は現在、学校プロジェクト、Spring Bootバックエンド、AngularJSフロントエンド用の単純なアプリケーションを作成していますが、 。ログイン失敗後にHttp-Basic-Authポップアップを表示するSpringブートセキュリティ

ログインは完全に機能しますが、間違ったパスワードを入力すると、デフォルトのログインポップアップが表示されます。これは迷惑です。私は、アノテーション 'BasicWebSecurity'を試して、httpBassicを無効にしましたが、結果はありません(つまり、ログイン・プロシージャーはまったく機能しません)。

マイセキュリティクラス:

package be.italent.security; 

import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.boot.autoconfigure.security.SecurityProperties; 
import org.springframework.context.annotation.Configuration; 
import org.springframework.core.annotation.Order; 
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; 
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; 
import org.springframework.security.config.annotation.web.builders.HttpSecurity; 
import org.springframework.security.config.annotation.web.builders.WebSecurity; 
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.web.csrf.CsrfFilter; 
import org.springframework.security.web.csrf.CsrfToken; 
import org.springframework.security.web.csrf.CsrfTokenRepository; 
import org.springframework.security.web.csrf.HttpSessionCsrfTokenRepository; 
import org.springframework.web.filter.OncePerRequestFilter; 
import org.springframework.web.util.WebUtils; 

import javax.servlet.Filter; 
import javax.servlet.FilterChain; 
import javax.servlet.ServletException; 
import javax.servlet.http.Cookie; 
import javax.servlet.http.HttpServletRequest; 
import javax.servlet.http.HttpServletResponse; 
import java.io.IOException; 

@Configuration 
@EnableGlobalMethodSecurity(prePostEnabled = true) 
@Order(SecurityProperties.ACCESS_OVERRIDE_ORDER) 
public class SecurityConfiguration extends WebSecurityConfigurerAdapter { 

    @Autowired 
    private UserDetailsService userDetailsService; 

    @Autowired 
    public void configure(AuthenticationManagerBuilder auth) throws Exception { 
     auth.userDetailsService(userDetailsService); 
    } 

    @Override 
    public void configure(WebSecurity web){ 
     web.ignoring() 
     .antMatchers("/scripts/**/*.{js,html}") 
     .antMatchers("/views/about.html") 
     .antMatchers("/views/detail.html") 
     .antMatchers("/views/home.html") 
     .antMatchers("/views/login.html") 
     .antMatchers("/bower_components/**") 
     .antMatchers("/resources/*.json"); 
    } 

    @Override 
    protected void configure(HttpSecurity http) throws Exception { 
     http.httpBasic() 
        .and() 
       .authorizeRequests() 
       .antMatchers("/user", "/index.html", "/", "/projects/listHome", "/projects/{id}", "/categories", "/login").permitAll().anyRequest() 
       .authenticated() 
        .and() 
       .csrf().csrfTokenRepository(csrfTokenRepository()) 
        .and() 
       .addFilterAfter(csrfHeaderFilter(), CsrfFilter.class).formLogin(); 
    } 

    private Filter csrfHeaderFilter() { 
     return new OncePerRequestFilter() { 
      @Override 
      protected void doFilterInternal(HttpServletRequest request, 
              HttpServletResponse response, FilterChain filterChain) 
        throws ServletException, IOException { 
       CsrfToken csrf = (CsrfToken) request.getAttribute(CsrfToken.class 
         .getName()); 
       if (csrf != null) { 
        Cookie cookie = WebUtils.getCookie(request, "XSRF-TOKEN"); 
        String token = csrf.getToken(); 
        if (cookie == null || token != null 
          && !token.equals(cookie.getValue())) { 
         cookie = new Cookie("XSRF-TOKEN", token); 
         cookie.setPath("/"); 
         response.addCookie(cookie); 
        } 
       } 
       filterChain.doFilter(request, response); 
      } 
     }; 
    } 

    private CsrfTokenRepository csrfTokenRepository() { 
     HttpSessionCsrfTokenRepository repository = new HttpSessionCsrfTokenRepository(); 
     repository.setHeaderName("X-XSRF-TOKEN"); 
     return repository; 
    } 
} 

誰でも休息を壊すことなく表示からこのポップアップを防ぐ方法についてのアイデアを持っていますか?

ソリューション

を追加しましたこれは私の角度設定に:

myAngularApp.config(['$httpProvider', 
    function ($httpProvider) { 
    $httpProvider.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest'; 
    } 
]); 
+0

セキュリティ設定が少し混乱しています。まず、httpBasicを有効にします。フォームのログインを使用して、httpBasicを無効にしたいとします。 私にとっては、あなたが何を保護したいのか、そしてどのようにしてそれを明確にしていないのですか。あなたはangleJS frontendを持っているようですが、その場合はcsrfHeaderFilterですか? –

+0

クラップ、間違ったコピー/貼り付けをしました。最終的なhttpBasic()。disable()はそこにあるはずです。私の悪い!それはまさに、角度のあるフロントエンドです。 – Daemun

+0

答えは数分で提供されます。うまくいけば、これはあなたが達成したいことです。コメントだけで私に知らせていない場合。 –

答えて

13

はのは、あなたの問題それは「春のブートセキュリティポップアップ」ではありません

そのブラウザのポップアップを見てみましょうあなたのSpring Bootアプリのレスポンスに次のヘッダが含まれていると表示されます:

WWW-Authenticate: Basic 

セキュリティ設定では、.formLogin()が表示されます。これは必須ではありません。あなたのAngularJSアプリケーションでフォームを使って認証したいのですが、フロントエンドは独立したjavascriptクライアントです。これはフォームログインの代わりにhttpBasicを使うべきです。

セキュリティ設定が

ようになりますどのように私は.formLogin()を削除:

@Override 
protected void configure(HttpSecurity http) throws Exception { 
    http 
      .httpBasic() 
       .and() 
      .authorizeRequests() 
      .antMatchers("/user", "/index.html", "/", "/projects/listHome", "/projects/{id}", "/categories", "/login").permitAll().anyRequest() 
      .authenticated() 
       .and() 
      .csrf().csrfTokenRepository(csrfTokenRepository()) 
       .and() 
      .addFilterAfter(csrfHeaderFilter(), CsrfFilter.class); 
} 

以前にポップアップを述べたように、ブラウザのポップアップ

に対処する方法場合現れますあなたのSpring Bootアプリのレスポンスには、ヘッダWWW-Authenticate: Basicが含まれています。これは、あなたが非常に簡単にあなたのブラウザでAPIを探索することができますので、これはあなたのSpring Bootアプリケーションのすべての要求に対して無効にすべきではありません。

Spring Securityには、各リクエスト内のSpring Bootアプリにこのヘッダをレスポンスに追加しないように指示するデフォルト設定があります。これはあなたの要求に次のヘッダーを設定することによって行われます:あなたのAngularJSアプリによって行われたすべての要求にこのヘッダーを追加する方法

X-Requested-With: XMLHttpRequest 

あなただけのアプリの設定でデフォルトのヘッダーを追加することができますようにこと:

yourAngularApp.config(['$httpProvider', 
    function ($httpProvider) { 
    $httpProvider.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest'; 
    } 
]); 

バックエンドは、今あなたが(例えばインターセプタによって)あなたの角度のアプリで処理するために持っていることを401応答で応答します。

これを行う方法の例が必要な場合は、私のshopping list appを見ることができます。その春のブートと角度jsで行われる。

関連する問題