1

I write REST service in Spring Boot and client application in Angular 5, and after successful login Angular app cannot read header by name, but in chrome developer tool Network I get all headers:

Chrome Response Headers:

Access-Control-Allow-Credentials:true
Access-Control-Allow-Origin:http://localhost:4200
Authorization:Bearer eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJhZG1pbi5hZG1pbkBnbWFpbC5jb20iLCJjcmVhdGVkIjoxNTE2NDc2MzMxNzIwLCJleHAiOjE1MTcwODExMzF9.pbytQyt1CywO2B8vo41ynhQ1VjzG9Wb-Bf-zpUkHNW9O4XWX4TD0A2PMyQJNlk-pCrgbxInHO67ibv4eAO8r0Q
Cache-Control:no-cache, no-store, max-age=0, must-revalidate
Content-Length:0
Date:Sat, 20 Jan 2018 19:25:41 GMT
Expires:0
Pragma:no-cache
Role:ADMIN
Vary:Origin
X-Application-Context:application:oracle:8091
X-Content-Type-Options:nosniff
X-Frame-Options:DENY
X-XSS-Protection:1; mode=block

But when I try to print it in console I didn't get these headers.

public login(loginRequest: LoginRequest): Observable<Response> {
    return this.http.post(
      this.loginUrl,
      JSON.stringify(loginRequest),
      { headers: this.headers }
    );
  }

public login() {
    console.log(this.request);

    this.loginService.login(this.request)
      .subscribe(res => {
        if (res.status === 200) {
          console.log('Response: ', res);
          console.log('authorization: ', res.headers.get('Authorization'));
        }
      }, error => {
        if (error.status === 401) {
          console.log('Error');
        }
      });
  }

The result is:

Response:  
Response {_body: "", status: 200, ok: true, statusText: "OK", headers: Headers, …} 
headers: Headers
   headers: Map(3) {"pragma" => Array(1), "cache-control" => Array(1), "expires" => Array(1)}
   normalizedNames: Map(3) {"pragma" => "pragma", "cache-control" => "cache-control", "expires" => "expires"}
   __proto__: Object
   ok: true
   status: 200
   statusText: "OK"
   type: 2
   url: "http://localhost:8091/login"
   _body: ""

And I don't know whose side is the fault therefore I have to attach also Spring Security configuration:

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private AuthenticationEntryPointImpl unauthorizedHandler;

    @Autowired
    private UserDetailsService userDetailsService;

    @Autowired
    private AuthenticationTokenFilter authenticationTokenFilter;

    @Autowired
    private BCryptPasswordEncoder passwordEncoder;

    @Autowired
    public void configureAuthentication(AuthenticationManagerBuilder authenticationManagerBuilder) throws Exception {
        authenticationManagerBuilder
                .userDetailsService(this.userDetailsService)
                .passwordEncoder(passwordEncoder);
    }

    @Override
    protected void configure(HttpSecurity httpSecurity) throws Exception {
        httpSecurity
                .csrf().disable()
                .exceptionHandling().authenticationEntryPoint(unauthorizedHandler)
                .and()
                .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                .and()
                .authorizeRequests()
                .antMatchers(
                        HttpMethod.POST,
                        "/register",
                        "/login"
                ).permitAll()
                .anyRequest().authenticated()
                .and().cors();

        httpSecurity.addFilterBefore(
                authenticationTokenFilter,
                UsernamePasswordAuthenticationFilter.class
        );

        httpSecurity
                .headers().cacheControl();
    }
user
  • 4,410
  • 16
  • 57
  • 83
  • I'm not too familiar with Angular JS but [this](https://stackoverflow.com/questions/28805589/how-to-read-response-headers-in-angularjs#28805641) answer and @trichetriche 's answer may be helpful for your problem. – Cataclysm Jan 20 '18 at 20:36
  • For server-side configuration , you have to configure CORS mappings as [this blog](https://spring.io/blog/2015/06/08/cors-support-in-spring-framework) describe. – Cataclysm Jan 20 '18 at 20:42
  • If you still has the problem about setting CORS setting , beware of the `@Order` of your Authorization server config. I strongly reconmended to check this [github issue](https://github.com/spring-projects/spring-security-oauth/issues/938) and aswers to achieve it. – Cataclysm Jan 20 '18 at 20:50

1 Answers1

2

Your issue is that angular hides all headers when your backend doesn't explicitly say to expose them.

This is done by adding a new header in your cors configuration. If I remember, the header is

Access-Control-Expose-Headers

And you must give your headers as values in this, such as

Authorization,Content-type

I'm on phone so I'm not that willing to look for more documentation online, sorry

  • Thanks. I added `exposedHeaders` to `@CrossOrigin` in my REST service and now it works! – user Jan 20 '18 at 21:29