3
votes

I am developing a website using Spring Boot 1.5.7 as back-end and Angular 2 as front-end. I am a newbie on both technologies, and it's the very first time I try to develop a website. So I am a bit confused on many things.

I have implemented user authentication through JWT. When the user logins through credentials, the backend verifies them and then creates a JWT and returns it to the frontend: the token is added to the header this way:

Authorization - Bearer <jwt token>

In the frontend I check out if that key is in the post response. If it is there, I add it along with the username to the localStorage.

private authUrl = 'http://localhost:8080/login';
private headers = new Headers({
    'Content-Type': 'application/json',
    'Accept': 'application/json'
});

constructor(private http: Http) { }

login(username: string, password: string): Observable<void> {
    let loginRequest = JSON.stringify({ username: username, password: password });

    return this.http.post(this.authUrl, loginRequest, { headers: this.headers })
        .map((response: Response) => {
            let token = response.headers.get('Authorization');
            // If token is not null, empty or undefined.
            if (token) {
                localStorage.setItem('jwt', JSON.stringify({ username: username, token: token }));
            }
        });
}

When the user is logged in, everytime he accessed a protected resource, a token will be retrieved from the localStorage and sent back to the backend for validation. The whole thing works. JWT are immune to CSRF, so I can disable that in the back-end,

@Override
protected void configure(HttpSecurity http) throws Exception {
    http.csrf().disable()
    ...

but I have read (for instance, here) that there are vulnerabilities when using localStorage.

In particular the localStorage is accessible through JavaScript on the same domain, exposing to XSS attacks. To resolve it seems I could use a JWT Cookie. As written in the link before, I could set the HttpOnly cookie flag to avoid cookies to be accessed through JavaScript.

But, with cookies I am now vulnerable to CRSF attacks.

Now, here, I have read Angular 2+ provides built-in, enabled by default, anti XSS.

So the question is. I should use localStorage and just use the embedded Angular 2 anti XSS feature, or is that not enough and then I should store JWTs on cookies to get protection against XSS attacks and then implement on top of it some kind of CRSF protection backend side using Spring Boot configuration?

Thank you

EDIT: the website is a sort of shopping cart. The user can view almost all pages, but to pay he needs to log in.

2

2 Answers

2
votes

Aniruddha Das approach is fine but client application will lost the token if user will refresh the browser because DOM will be reloaded with browser refresh and all memory data including token will be lost.

Now come back to your approach-

  1. Local storage - CSRF attack is not possible using this approach and application will be stateless but it is prone to XSS attack. By default Angular do the output encoding to prevent the XSS attack but risk is still there with server side Angular template. To mitigate the XSS attack, you can reduce the token expiry time and encrypt it, if there is some sensitive information.
  2. Cookie approach - HTTP cookie will mitigate the XSS attack but you have to implement the CSRF protection. You have to use the API gateway pattern to make the application stateless.

Both approach have prons/cons and you have to select depending on your application. If your application is related to financial domain then I would suggest cookie based approach.

1
votes

In angular you can hold your token in service and use it when ever it required. Like pojo in java in angular you can create a angular service with getter and setter to hold the token. Provide that service to the module and it will available in all component and directives.

The token will be in memory while the application is open in the browser and will be be stored in the browser.

I would say use a observable/Subject type variable so that it will wait until the token is extracted from server and use that to do stuffs.