简体   繁体   English

安全性:Java Spring Boot + Angular 2 + JWT

[英]Securirty: Java Spring Boot + Angular 2 + JWT

I am developing a website using Spring Boot 1.5.7 as back-end and Angular 2 as front-end.我正在开发一个使用Spring Boot 1.5.7作为后端和Angular 2作为前端的网站。 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 .我已经通过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:当用户通过凭据登录时,后端会验证它们,然后创建一个 JWT 并将其返回给前端:令牌以这种方式添加到标头中:

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 .如果存在,我会将其与用户名一起添加到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.用户登录后,每次访问受保护的资源时,都会从localStorage 中获取token 并发送回后端进行验证。 The whole thing works.整件事都有效。 JWT are immune to CSRF, so I can disable that in the back-end, JWT 不受 CSRF 的影响,所以我可以在后端禁用它,

@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.但我读过(例如, 这里)使用 localStorage 时存在漏洞。

In particular the localStorage is accessible through JavaScript on the same domain, exposing to XSS attacks.特别是 localStorage 可通过同一域上的 JavaScript 访问,从而暴露于XSS攻击。 To resolve it seems I could use a JWT Cookie.为了解决这个问题,我似乎可以使用 JWT Cookie。 As written in the link before, I could set the HttpOnly cookie flag to avoid cookies to be accessed through JavaScript.正如之前链接中所写,我可以设置 HttpOnly cookie 标志以避免通过 JavaScript 访问 cookie。

But, with cookies I am now vulnerable to CRSF attacks.但是,有了 cookie,我现在很容易受到CRSF攻击。

Now, here , I have read Angular 2+ provides built-in, enabled by default, anti XSS.现在,在这里,我已经阅读了 Angular 2+ 提供了内置的、默认启用的、反 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?我应该使用 localStorage 并且只使用嵌入的 Angular 2 anti XSS 功能,或者这还不够,然后我应该将 JWT 存储在 cookie 上以防止 XSS 攻击,然后在它上面使用 Spring 实现某种 CRSF 保护后端启动配置?

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.用户几乎可以查看所有页面,但要付费,他需要登录。

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. Aniruddha Das 方法很好,但如果用户刷新浏览器,客户端应用程序将丢失令牌,因为 DOM 将随着浏览器刷新而重新加载,并且包括令牌在内的所有内存数据都将丢失。

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.本地存储 - 使用这种方法无法进行 CSRF 攻击,应用程序将是无状态的,但容易受到 XSS 攻击。 By default Angular do the output encoding to prevent the XSS attack but risk is still there with server side Angular template.默认情况下,Angular 执行输出编码以防止 XSS 攻击,但服务器端 Angular 模板仍然存在风险。 To mitigate the XSS attack, you can reduce the token expiry time and encrypt it, if there is some sensitive information.为了减轻 XSS 攻击,如果有一些敏感信息,您可以减少令牌到期时间并对其进行加密。
  2. Cookie approach - HTTP cookie will mitigate the XSS attack but you have to implement the CSRF protection. Cookie 方法 - HTTP cookie 将减轻 XSS 攻击,但您必须实施 CSRF 保护。 You have to use the API gateway pattern to make the application stateless.您必须使用 API 网关模式使应用程序无状态。

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.如果您的应用程序与金融领域相关,那么我建议使用基于 cookie 的方法。

In angular you can hold your token in service and use it when ever it required.在 angular 中,您可以保留您的令牌并在需要时使用它。 Like pojo in java in angular you can create a angular service with getter and setter to hold the token.就像 angular 中的 java 中的pojo一样,您可以使用 getter 和 setter 创建一个 angular 服务来保存令牌。 Provide that service to the module and it will available in all component and directives .向模块提供该服务,它将在所有componentdirectives可用。

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.我会说使用 observable/Subject 类型变量,这样它就会等到令牌从服务器中提取出来并使用它来做事情。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM