Spring Boot security zeigt die Http-Basic-Auth popup nach login fehlgeschlagen
Ich bin derzeit auf der Erstellung einer einfachen app für ein Schulprojekt, Spring-Boot-backend und AngularJS frontend, aber habe ein problem mit der Sicherheit, dass ich kann nicht scheinen, um zu lösen.
Einloggen funktioniert einwandfrei, aber wenn ich ein Falsches Passwort die Standard-login-popup zeigt sich, das ist ziemlich ärgerlich. Ich habe versucht, die annotation 'BasicWebSecurity' und setzen httpBassic auf deaktiviert, aber ohne Ergebnis (was bedeutet, dass die login-Prozedur funktioniert überhaupt nicht mehr).
Meinem Sicherheit Klasse:
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;
}
}
Hat jemand eine Idee, wie man verhindern, dass dieses Fenster aus zeigen, ohne zu brechen den rest?
Lösung
Hinzugefügt, das zu meinem Winkel-config:
myAngularApp.config(['$httpProvider',
function ($httpProvider) {
$httpProvider.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';
}
]);
- Ihre Sicherheit config sieht ein bisschen verwirrend. Zuerst schalten Sie httpBasic. dann wollen Sie verwenden form-login und klicken Sie deaktivieren möchten httpBasic. Für mich ist es nicht klar, WAS Sie schützen möchten, und in welcher Weise. Die csrfHeaderFilter sieht aus wie Sie haben eine angularJS frontend ist das der Fall?
- Mist, ich habe eine falsche copy/paste. Die endgültige httpBasic().disable() soll nicht da sein. Mein schlechtes! Es ist in der Tat ein angularJS frontend.
- Ok. Eine Antwort erhalten Sie in wenigen Minuten. Hoffentlich ist das, was Sie erreichen wollen. Wenn nicht, lasst es mich einfach in den Kommentaren wissen.
- Ist dein problem nun behoben?
- Ja, vielen Dank, Mann!
Du musst angemeldet sein, um einen Kommentar abzugeben.
Starten wir mit deinem problem
Es ist nicht ein "Spring-Boot-Sicherheits-popup" es ist ein browser-popup wird angezeigt, wenn die Antwort der Spring-Boot-app enthält die folgenden header:
In Ihre security-Konfiguration zu einer
.formLogin()
zeigt sich. Dies sollte nicht erforderlich sein. Wenn Sie möchten, um die Authentifizierung über ein Formular in der AngularJS-Anwendung auf dem frontend ist eine unabhängige javascript-client verwenden soll httpBasic statt des form-login., Wie Ihre Sicherheit config Aussehen könnte
Entfernte ich die
.formLogin()
:, Wie man mit der browser-popup
Wie bereits erwähnt die popup-zeigt, ob die Antwort der Spring-Boot-app enthält die header -
WWW-Authenticate: Basic
. Dies sollte nicht deaktiviert werden, für alle Anforderungen in Spring-Boot-app, da es ermöglicht es Ihnen, erkunden Sie die api in Ihrem browser sehr leicht.Spring Security hat eine Standard-Konfiguration, die Ihnen erlaubt zu sagen, das Spring-Boot-app in jedem Antrag nicht, fügen Sie diese header in der Antwort. Dies geschieht, indem der folgende header zu Ihrer Anfrage:
So fügen Sie diesen header, um jeder Anforderung von Ihrem AngularJS app
Können Sie fügen Sie einfach einen Standard-header in der app-config so:
Backend reagieren nun mit einer 401-Antwort, die Sie behandeln müssen, die durch Ihre Winkel-app (von einem interceptor zum Beispiel).
Wenn Sie benötigen, ein Beispiel, wie dies zu tun haben, könnten Sie einen Blick auf meine Einkaufsliste app. Fertig mit spring boot und angular js.
Als Yannic Klem schon sagte, das ist passiert, weil der header
Aber es ist ein Weg, im Frühjahr, um Sie auszuschalten, und es ist wirklich einfach. In Ihrer Konfiguration nur hinzufügen:
und da authenticationEntryPoint ist noch nicht definiert, autowire es am Anfang:
Und erstellen Sie jetzt MyBasicAuthenticationEntryPoint.class und fügen Sie den folgenden code:
Nun Ihre app nicht senden WWW-Authenticate: Basic header, weil der pop-up-Fenster wird nicht angezeigt, und es gibt keine Notwendigkeit zu Chaos mit überschriften in Eckigen.