使用JWT和基本身份验证保护REST应用程序是否有意义? [英] Does securing a REST application with a JWT and Basic authentication make sense?

查看:71
本文介绍了使用JWT和基本身份验证保护REST应用程序是否有意义?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个Spring REST应用程序,该应用程序最初是通过基本身份验证来保护的.

I have a Spring REST application which at first was secured with Basic authentication.

然后,我添加了一个登录控制器,该控制器创建了一个JWT JSON Web令牌,该令牌在后续请求中使用.

Then I added a login controller that creates a JWT JSON Web Token which is used in subsequent requests.

是否可以将以下代码从登录控制器中移出,并移至安全过滤器中?然后,我将不再需要登录控制器.

Could I move the following code out of the login controller and into the security filter? Then I would not need the login controller any longer.

tokenAuthenticationService.addTokenToResponseHeader(responseHeaders, credentialsResource.getEmail());

还是可以删除基本身份验证?

Or could I remove the Basic authentication?

将基本身份验证与JWT混合在一起是一个好设计吗?

Is it a good design to mix Basic authentication with a JWT?

尽管一切正常,但为了最好地设计此安全性,我还是有点茫然.

Although it all works fine, I'm a bit in the dark here as to best design this security.

推荐答案

假设所有通信的100%TLS(在登录期间以及登录后的所有时间)-通过基本身份验证使用用户名/密码进行身份验证并以交换方式接收JWT是一种有效的用例.这几乎是Oem 2的流程之一(密码授予")的工作原理.

Assuming 100% TLS for all communication - both during and at all times after login - authenticating with username/password via basic authentication and receiving a JWT in exchange is a valid use case. This is almost exactly how one of OAuth 2's flows ('password grant') works.

这个想法是,最终用户通过一个端点进行身份验证,例如/login/token使用所需的任何机制,并且响应应包含将在所有后续请求上发送回的JWT. JWT应该是具有正确的JWT到期时间(exp)字段的JWS(即,经过加密签名的JWT):这样可确保客户端无法操纵JWT或使其寿命更长.

The idea is that the end user is authenticated via one endpoint, e.g. /login/token using whatever mechanism you want, and the response should contain the JWT that is to be sent back on all subsequent requests. The JWT should be a JWS (i.e. a cryptographically signed JWT) with a proper JWT expiration (exp) field: this ensures that the client cannot manipulate the JWT or make it live longer than it should.

您也不需要X-Auth-Token头:为此确切的用例创建了HTTP身份验证Bearer方案:基本上,跟随Bearer方案名称的任何信息都是承载"信息,被验证.您只需设置Authorization标头:

You don't need an X-Auth-Token header either: the HTTP Authentication Bearer scheme was created for this exact use case: basically any bit of information that trails the Bearer scheme name is 'bearer' information that should be validated. You just set the Authorization header:

Authorization: Bearer <JWT value here>

但是,话虽这么说,如果您的REST客户端是不受信任的"(例如,启用JavaScript的浏览器),我什至不会这样做:HTTP响应中可通过JavaScript访问的任何值-基本上是任何标头值或响应主体值-可以通过MITM XSS攻击来监听和拦截.

But, that being said, if your REST client is 'untrusted' (e.g. JavaScript-enabled browser), I wouldn't even do that: any value in the HTTP response that is accessible via JavaScript - basically any header value or response body value - could be sniffed and intercepted via MITM XSS attacks.

最好将JWT值存储在仅安全,仅HTTP的cookie中(cookie配置:setSecure(true),setHttpOnly(true)).这样可以保证浏览器将:

It's better to store the JWT value in a secure-only, http-only cookie (cookie config: setSecure(true), setHttpOnly(true)). This guarantees that the browser will:

  1. 仅通过TLS连接传输cookie,并且
  2. 永远不要使cookie值可用于JavaScript代码.

这种方法几乎是您为最佳做法安全所需要做的一切.最后一件事是确保对每个HTTP请求都具有CSRF保护,以确保向您的站点发起请求的外部域无法正常运行.

This approach is almost everything you need to do for best-practices security. The last thing is to ensure that you have CSRF protection on every HTTP request to ensure that external domains initiating requests to your site cannot function.

最简单的方法是设置一个具有随机值的安全(仅非HTTP唯一)cookie,例如一个UUID.

The easiest way to do this is to set a secure only (but NOT http only) cookie with a random value, e.g. a UUID.

然后,在对服务器的每个请求中,确保您自己的JavaScript代码读取cookie值并将其设置在自定义标头中,例如X-CSRF-Token并在服务器中的每个请求上验证该值.外部域客户端无法为向您的域的请求设置自定义标头,除非外部客户端通过HTTP Options请求获得授权,因此任何CSRF攻击尝试(例如在IFrame中,无论如何)都会使它们失败.

Then, on every request into your server, ensure that your own JavaScript code reads the cookie value and sets this in a custom header, e.g. X-CSRF-Token and verify that value on every request in the server. External domain clients cannot set custom headers for requests to your domain unless the external client gets authorization via an HTTP Options request, so any attempt at a CSRF attack (e.g. in an IFrame, whatever) will fail for them.

这是当今我们知道的可用于Web上不受信任的JavaScript客户端的最佳安全性. Stormpath在这些技术上写了一篇文章如果您好奇的话.

This is the best of breed security available for untrusted JavaScript clients on the web today that we know of. Stormpath wrote an article on these techniques as well if you're curious.

最后, Stormpath Java Servlet插件 已经完成了所有操作 (还有很多很酷的功能,包括附加的自动安全检查),因此您不必自己编写它-或更糟-自己维护它.查看 HTTP请求身份验证部分和表单/Ajax示例,了解如何使用它. HTH!

Finally, the Stormpath Java Servlet Plugin already does all of this for you (and a lot more cool stuff, including additional automated security checks), so you don't ever have to write it - or worse - maintain it yourself. Check out the HTTP Request Authentication section and the Form/Ajax example to see how to use it. HTH!

这篇关于使用JWT和基本身份验证保护REST应用程序是否有意义?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆