Java – spring boot security displays HTTP basic auth pop-up window after login failure
I am currently creating a simple application for the school project, spring boot back end and angularjs front end, but I can't seem to solve the security problem
Login works perfectly, but when I enter the wrong password, the default login pop-up appears, which is a little annoying I've tried commenting 'basic web security' and disabling httpbasic, but it didn't work (meaning the login process didn't work at all)
My security class:
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;
}
}
Does anyone know how to prevent this pop-up from displaying without breaking the rest?
solution
Add this to my angular configuration:
myAngularApp.config(['$httpProvider',function ($httpProvider) {
$httpProvider.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';
}
]);
Solution
Let's start with your question
If the response of the spring boot application contains the following title, it is not a "spring boot security pop-up window", it is a displayed browser pop-up window:
WWW-Authenticate: Basic
In your security configuration, the formLogin(). This should not be necessary Although you want to authenticate through forms in the angularjs application, your front end is a separate JavaScript client that should log in using httpbasic instead of forms
How is your security configuration
I deleted it formLogin():
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.httpBasic()
.and()
.authorizeRequests()
.antMatchers("/user","/login").permitAll().anyRequest()
.authenticated()
.and()
.csrf().csrfTokenRepository(csrfTokenRepository())
.and()
.addFilterAfter(csrfHeaderFilter(),CsrfFilter.class);
}
How to handle browser pop ups
As mentioned earlier, if the response of the spring boot application contains the title www authenticate: basic, a pop-up window will be displayed This feature should not be disabled for all requests in spring boot applications, as it allows you to easily browse the APIs in your browser
Spring security has a default configuration that allows you to tell spring boot applications in each request not to add this header to the response This can be done by setting the following headers for your request:
X-Requested-With: XMLHttpRequest
How to add this header to each request issued by the angularjs application
You can add a default header in the application configuration as follows:
yourAngularApp.config(['$httpProvider',function ($httpProvider) {
$httpProvider.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';
}
]);
The back end will now respond to a 401 response, which you must handle through the angle application (such as an interceptor)
If you need an example of how to do this, you can view my shopping list app It completes the spring start and angle JS
