SlimenTN
SlimenTN

Reputation: 3564

Spring: Authorization header is always null via Angular app

I'm building an application with Spring and Angular and for now, I'm trying to implement the security phase using Spring security and (JWT)
The problem is that when I send the Authorization header from Angular Spring does not receive it!
even tho I'm sure it's already in the request (from chrome dev tools).
Also when I send the same request with the same header from ARC (Advanced REST Client from chrome) spring receives it and returns the data!
On then Angular side I'm using the HttpInterceptor of course to add the token to requests like so:

export class HttpInterceptorService implements HttpInterceptor{
  private _api = `${environment.api}/api`;
  constructor(
    private _authService: AuthenticationService
  ) { }

  intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>>{

    if(req.url.startsWith(this._api)){
      req = req.clone({
        setHeaders: {
          Authorization: `Bearer ${this._authService.getToken()}`
        }
      });
    }
    
    return next.handle(req);
  }
}

enter image description here

And this is what I'm doing inside spring:

@Component
public class JwtRequestFilter extends OncePerRequestFilter {

    @Autowired
    private JwtUserDetailsService jwtUserDetailsService;

    @Autowired
    private JwtTokenUtil jwtTokenUtil;

    private List<String> excludedURLsPattern = Arrays.asList(new String[]{"/authenticate"});

    @Override
    protected boolean shouldNotFilter(HttpServletRequest request) throws ServletException {

        return excludedURLsPattern
                .stream()
                .anyMatch(urlPattern -> request.getRequestURL().toString().contains(urlPattern));

    }

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
            throws ServletException, IOException {

        System.out.println("=== request URL: "+request.getRequestURL());
        final String requestTokenHeader = request.getHeader("Authorization");
        System.out.println("=== requestTokenHeader: "+requestTokenHeader);// in this line I always get null (when using Angular not ARC) !!

        String username = null;
        String jwtToken = null;
        // JWT Token is in the form "Bearer token". Remove Bearer word and get
        // only the Token
        if (requestTokenHeader != null && requestTokenHeader.startsWith("Bearer ")) {
            jwtToken = requestTokenHeader.substring(7);
            try {
                username = jwtTokenUtil.getUsernameFromToken(jwtToken);
            } catch (IllegalArgumentException e) {
                System.out.println("Unable to get JWT Token");
            } catch (ExpiredJwtException e) {
                System.out.println("JWT Token has expired");
            }
        } else {
            logger.warn("JWT Token does not begin with Bearer String");
        }

        // Once we get the token validate it.
        if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) {

            UserDetails userDetails = this.jwtUserDetailsService.loadUserByUsername(username);

            // if token is valid configure Spring Security to manually set
            // authentication
            if (jwtTokenUtil.validateToken(jwtToken, userDetails)) {

                UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken = new UsernamePasswordAuthenticationToken(
                        userDetails, null, userDetails.getAuthorities());
                usernamePasswordAuthenticationToken
                        .setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
                // After setting the Authentication in the context, we specify
                // that the current user is authenticated. So it passes the
                // Spring Security Configurations successfully.
                SecurityContextHolder.getContext().setAuthentication(usernamePasswordAuthenticationToken);
            }
        }
        chain.doFilter(request, response);
    }

}

And this is the message I get:

2020-10-14 15:11:17.664  WARN 9856 --- [nio-5000-exec-1] c.s.c.security.config.JwtRequestFilter   : JWT Token does not begin with Bearer String

Upvotes: 4

Views: 1902

Answers (2)

Dnyaneshwar Jadhav
Dnyaneshwar Jadhav

Reputation: 353

Springboot-3

under your security configuration class public SecurityFilterChain filterChain(HttpSecurity http) bean add following line before http.build() anywhere cors(Customizer.withDefaults()) and create a new class as global configuration CorsConfiguration implement method addCorsMapping from WebMvcConfigurer class, finally allow methods, originas, header under implemented method, this should work

Upvotes: 0

SlimenTN
SlimenTN

Reputation: 3564

ok I will leave the solution here in case someone needed it.
as described in this blog and since I'm using Sring Security I must enable CORS at Spring security level

@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.cors().and()...// this one right here
    }
}

Upvotes: 3

Related Questions