Pneumokok Pneumokok - 4 months ago 32
Javascript Question

Spring Security does not throw Error when authorization header is not present after login with AngularJS

I follow Spring Security and Angular JS for HTTP Basic authentication, by adding Authorization header to $http headers:

const headers = {
authorization: "Basic " + btoa(this.login + ":" + this.password)
};

this._$http.get("user",
{
headers: headers,
})
.then(
this.showUser.bind(this),
this.showError.bind(this)
);


Inside
showUser
I redirect to
jobs
component with
$location
:

this._$location.path("jobs");


And inside
jobs
component, I load available jobs:

public $onInit() {
this._$http.get("jobs").then(function(response) {
this.jobs = response.data;
}.bind(this));
this.authenticated = this._loginService.isLogged();
}


Intentionally without authorization header, to prove everything work. I thought it should be abandon by
Spring Security
with
HTTP 401 Unauthorized
or something like that, but it worked without authorization header. When I logout from another browser window and reload jobs it's OK, jobs aren't loaded. But I think (and I hope) authorization data (HTTP Basic) should be present in every request. Here's my security config:

protected void configure(HttpSecurity http) throws Exception {
http
.formLogin()
.successHandler(
new DifferentRoleBasedStartingURLsAuthenticationSuccessHandler()
)
.and()
.logout()
.logoutUrl("/logout")
.and()
.httpBasic()
.and()
.authorizeRequests()
.antMatchers("/jobs/**").authenticated()
.antMatchers("/interviews/**").authenticated()
.anyRequest().permitAll()
.and()
.csrf()
.csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())
;


Maybe here I made a mistake. I think rule
.antMatchers("/jobs/**").authenticated()
should make
jobs/
also authenticated. Can you help me? Thank you in advance.




UPDATE 2016-07-31:
Maybe authorization headers are not needed with every request in Spring with Angular? My repo is here: Playground for Spring and Angular (AngularJS branch), password is
test
for every created user.

Answer

If you're using Basic Authentication then it doesn't make much sense to also configure form login in spring. When using basic authentication, the http Authorization header needs to be present for each request that requires authentication on the server. If no authorization header is present for a protected resource, Spring returns a 401 response.

Your setup looks correct to me (and yes, "/jobs/**" matches "/jobs"), but I guess your experiment to verify if the security constraints are working failed because the server also sets a jsessionid cookie that can be used to authenticate you. So if you request a protected resoure without Authorization header but with a valid jsessionid cookie than the server can still authenticate you.

You can disable jsessionid cookie creation by setting the session creation policy to never.

Try the following security configuration:

protected void configure(HttpSecurity http) throws Exception {
    http.httpBasic()
            .and()
            .authorizeRequests()
            .antMatchers("/jobs/**").authenticated()
            .antMatchers("/interviews/**").authenticated()
            .anyRequest().permitAll()
            .and()
            .csrf()
            .csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())
            .and()
            .sessionManagement()
            .sessionCreationPolicy(SessionCreationPolicy.NEVER)
            .and();
}