Reputation: 4642
I'm building a Angular 2 web client that tries to do a POST to a server using SpringBoot Security. How should I write my Spring security configuration?
My Angular call for authentication:
public login(username, password) {
let body = JSON.stringify({username: username, password: password});
let headers = new Headers({'Content-Type': 'application/json'});
let options = new RequestOptions({headers: headers});
this.http.post("http://localhost:8080/login", body, options)
.subscribe(
res => this.loggedIn = true,
err => console.error("failed authentication: " + err),
() => console.log("tried authentication")
);
}
The authentication fails with the error:
{"timestamp":1487007177889,"status":401,"error":"Unauthorized","message":"Authentication Failed: Empty Username","path":"/login"}
My spring security configuration:
@Configuration
public class WebSecurityConfigurer extends WebSecurityConfigurerAdapter {
@Autowired
private RestAuthenticationEntryPoint restAuthenticationEntryPoint;
@Autowired
private RestAuthenticationSuccessHandler restAuthenticationSuccessHandler;
@Autowired
private RestAuthenticationFailureHandler restAuthenticationFailureHandler;
@Autowired
private RestLogoutSuccessHandler restLogoutSuccessHandler;
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable()
.exceptionHandling()
.authenticationEntryPoint(restAuthenticationEntryPoint)
.and().formLogin()
.loginProcessingUrl("/login")
.usernameParameter("username")
.passwordParameter("password")
.successHandler(restAuthenticationSuccessHandler)
.failureHandler(restAuthenticationFailureHandler)
.permitAll()
.and().logout()
.logoutUrl("/logout")
.logoutSuccessHandler(restLogoutSuccessHandler)
.permitAll()
.and().authorizeRequests().anyRequest().authenticated()
;
}
@Override
public void configure(AuthenticationManagerBuilder builder) throws Exception {
// This configuration has been tested, it works.
// It has been removed for better readability
}
@Bean
public LdapContextSource contextSource() {
// This configuration has been tested, it works.
// It has been removed for better readability
}
}
Upvotes: 1
Views: 1363
Reputation: 208974
You're supposed to use application/x-www-form-urlencoded
parameters for form login, not JSON. That's why the error is saying that the username is missing, because Spring Security it trying to get it from the HttpServletRequest#getParameters. To send form parameters in Angular, you can do
import { URLSearchParams } from '@angular/http';
let params = new URLSearchParams();
params.set('username', username);
params.set('password', password);
If you set it as the body parameter of the Http request, it should (from what I remember) automatically be serialized to the correct format, i.e.
username=xxx&password=xxx
And I don't think you need to set the header Content-Type
to applicatio/x-www-form-urlencoded
either. I think that should also be set for you when Angular detects URLSearchParams
as the body.
Upvotes: 1