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

3
我正在开发一个网站,后端使用 Spring Boot 1.5.7,前端使用 Angular 2。由于我对这两种技术都是新手,所以在很多事情上我还有些困惑。
我已经用 JWT 实现了用户身份验证。当用户通过凭据登录时,后端会验证凭据并创建一个 JWT,并将其返回到前端:token 以此方式添加到头部:
Authorization - Bearer <jwt token>

在前端中,我会检查帖子响应中是否存在该键。如果有,我会将其与用户名一起添加到本地存储中。

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 }));
            }
        });
}

当用户登录后,每次访问受保护的资源时,将从localStorage中检索令牌并发送回后端进行验证。 整个过程都可以正常工作。JWT对CSRF免疫,因此我可以在后端禁用它。

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

我已阅读(例如,这里),使用localStorage存在漏洞。
特别是,同一域上的JavaScript可以访问localStorage,从而暴露了XSS攻击的风险。解决方法似乎是使用JWT Cookie。如之前链接中所写,我可以设置HttpOnly cookie标志以避免JavaScript访问cookie。
但是,使用cookie后我就容易受到CRSF攻击的影响。
现在,在这里,我已经了解到Angular 2+提供了内置的默认启用的反XSS功能。
所以问题是,我应该使用localStorage并只使用嵌入式Angular 2反XSS功能,还是那不够安全,然后我应该将JWT存储在cookie中以获得对XSS攻击的保护,并在其上实施某种CRSF保护后端侧使用Spring Boot配置?
谢谢
2个回答

2
Aniruddha Das的方法是不错的,但如果用户刷新浏览器,客户端应用程序将失去令牌,因为DOM将重新加载,所有内存数据(包括令牌)都将丢失。
现在回到你的方法-
1.本地存储 - 使用此方法无法进行CSRF攻击,并且应用程序将是无状态的,但容易受到XSS攻击。默认情况下,Angular进行输出编码以防止XSS攻击,但仍存在使用服务器端Angular模板的风险。为了缓解XSS攻击,可以减少令牌过期时间并加密它,如果有一些敏感信息。
2.Cookie方法 - HTTP cookie将缓解XSS攻击,但您必须实施CSRF保护。您必须使用API网关模式使应用程序无状态。
这两种方法都有优缺点,您必须根据您的应用选择。如果您的应用程序涉及金融领域,则建议使用基于cookie的方法。

谢谢您的回答。我已经编辑了问题;我的网站将是一种购物车。在这种情况下,遵循方法#2会更好吗? - Shaunyl

1
在 Angular 中,您可以将令牌存储在服务中,并在需要时使用它。就像 Java 中的 pojo 一样,在 Angular 中,您可以创建一个带有 getter 和 setter 的 Angular 服务来保存令牌。将该服务提供给模块,它将在所有的 componentdirectives 中可用。

应用程序在浏览器中打开时,令牌将在内存中,并且将被存储在浏览器中。

建议使用 observable/Subject 类型的变量,以便等待从服务器提取令牌并使用其执行操作。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接