jhipster oauth2客户端机密 [英] jhipster oauth2 client secret

查看:66
本文介绍了jhipster oauth2客户端机密的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在试验jhipster. 我已将我的应用程序配置为可与oauth2一起使用. 为此,我的application.yml中有一个客户机密

根据我在该主题上发现的几篇文章,应该始终将客户机密保密.例如,检查 https://aaronparecki.com/articles/2012/07 /29/1/oauth2-simplified

必须对客户机密保密.如果已部署的应用程序无法对机密信息(例如Javascript或本机应用程序)保密,则不会使用该机密信息.

我注意到,虽然生成的auth.oauth2.service.js包含纯文本的机密:

         return {
            login: function(credentials) {
                var data = "username=" + credentials.username + "&password="
                    + credentials.password + "&grant_type=password&scope=read%20write&" +
                    "client_secret=mySecretOAuthSecret&client_id=myapp";
                return $http.post('oauth/token', data, {
                    headers: {
                        "Content-Type": "application/x-www-form-urlencoded",
                        "Accept": "application/json",
                        "Authorization": "Basic " + Base64.encode("myapp" + ':' + "mySecretOAuthSecret")
                    }
                }).success(function (response) {
                    var expiredAt = new Date();
                    expiredAt.setSeconds(expiredAt.getSeconds() + response.expires_in);
                    response.expires_at = expiredAt.getTime();
                    localStorageService.set('token', response);
                    return response;
                });
            }, 

我知道在精简的javascript中会很难找到,但是任何寻找"client_secret"的人都会很快得到奖励.

我错过了什么吗?还是jHipster oauth实施不安全?

谢谢, 安迪

解决方案

由于jhipster之类的JS客户端无法保留客户端秘密的秘密",因此完全不使用客户端秘密是没有意义的. jhipster使用的OAuth2资源所有者密码凭证授予流是针对非常受信任的客户端的,即jhipster的客户端.它允许您跳过常规的授权"端点,而直接转到令牌"端点以使用用户凭据获取令牌.如果您的Spring Authorization Server(AS)定义了一个客户端秘密,则需要从客户端JS传递该秘密.但是,如果您从AS的内存中客户端设置中删除秘密定义(例如,在OAuth2ServerConfiguration.java中将该行注释掉),则可以在JS中将其完全删除(请参见下文)

 return {
   login: function(credentials) {
      var data = "username=" + credentials.username + "&password=" + credentials.password + "&grant_type=password&scope=read%20write&";
      return $http.post('oauth/token', data, {
         headers: {
            "Content-Type": "application/x-www-form-urlencoded",
            "Accept": "application/json",
            "Authorization": "Basic " + Base64.encode("myapp" + ':' + "")
         }
      }).success(function (response) {
         var expiredAt = new Date();
         expiredAt.setSeconds(expiredAt.getSeconds() + response.expires_in);
         response.expires_at = expiredAt.getTime();
         localStorageService.set('token', response);
         return response;
      });
   }, 

删除客户端秘密后,我认为您的应用程序确实没有任何安全性,但是它看上去更干净,更诚实-因为您承认使用纯JS客户端,所以只能这样做安全的.对于JS和本机客户端,通常使用隐式流,并且不会因客户端秘密而烦恼.由于使用JS或本机客户端无法保存机密这一事实,它从更强大的授权代码授予流程中简化了.

无论如何,jhipster可能不应该在JS源代码中包含客户端机密,但是我不认为这会造成任何危害(因为唯一的选择就是拥有一个空白的客户端机密,它不再安全了) .您并非不安全(因为规范允许这种事情发生),但是使用授权代码流(在jhipster实现中需要一些工作)或使用轻量级的服务器代理添加客户端,您会更安全.对令牌"端点的请求的秘密,而不是直接来自JS的秘密.服务器到服务器的通信(例如,通过代理)使秘密远离浏览器的视线.

请参阅此帖子,以更好地讨论使用oauth2的纯JS客户端的陷阱: http://alexbilbie.com/2014/11/oauth-and-javascript/

以下是将oauth2与angularjs一起使用并在代理上使用spring的示例:https://aaronparecki.com/articles/2012/07/29/1/oauth2-simplified

The client secret must be kept confidential. If a deployed app cannot keep the secret confidential, such as Javascript or native apps, then the secret is not used.

I've noticed though that the generated auth.oauth2.service.js contains the secret in plain text:

        return {
            login: function(credentials) {
                var data = "username=" + credentials.username + "&password="
                    + credentials.password + "&grant_type=password&scope=read%20write&" +
                    "client_secret=mySecretOAuthSecret&client_id=myapp";
                return $http.post('oauth/token', data, {
                    headers: {
                        "Content-Type": "application/x-www-form-urlencoded",
                        "Accept": "application/json",
                        "Authorization": "Basic " + Base64.encode("myapp" + ':' + "mySecretOAuthSecret")
                    }
                }).success(function (response) {
                    var expiredAt = new Date();
                    expiredAt.setSeconds(expiredAt.getSeconds() + response.expires_in);
                    response.expires_at = expiredAt.getTime();
                    localStorageService.set('token', response);
                    return response;
                });
            },

I understand that it will be a little bit harder to find in the minified javascript, but anyone looking for 'client_secret' will be rewarded quickly.

Am I missing something? Or is the jHipster oauth implementation unsafe?

Thanks, Andy

解决方案

Since a JS client like jhipster's can't keep the client-secret "secret", it doesn't make sense to use the client-secret at all. The OAuth2 Resource Owner Password Credentials Grant flow that jhipster uses is for very trusted clients--which the client side of jhipster is. It allows for you to skip the normal "authorize" endpoint and go directly to the "token" endpoint to get your tokens with your user credentials. If your Spring Authorization Server (AS) defines a client-secret, you'll need to pass that secret along from the client JS. However, if you remove the secret definition from your in-memory client setup in your AS (e.g. comment out that line in OAuth2ServerConfiguration.java), you can leave it out altogether in your JS (see below)

return {
   login: function(credentials) {
      var data = "username=" + credentials.username + "&password=" + credentials.password + "&grant_type=password&scope=read%20write&";
      return $http.post('oauth/token', data, {
         headers: {
            "Content-Type": "application/x-www-form-urlencoded",
            "Accept": "application/json",
            "Authorization": "Basic " + Base64.encode("myapp" + ':' + "")
         }
      }).success(function (response) {
         var expiredAt = new Date();
         expiredAt.setSeconds(expiredAt.getSeconds() + response.expires_in);
         response.expires_at = expiredAt.getTime();
         localStorageService.set('token', response);
         return response;
      });
   },

After removing your client-secret, I don't think your app is really any safer but it feels a bit cleaner and honest--in that you're acknowledging that using a JS-only client, you can only be so safe. For JS and native clients, the implicit flow is typically used and it doesn't bother with a client-secret. It's simplified from the more robust authorization code grant flow for the fact that with a JS or native client can't keep a secret.

Anyway, jhipster probably shouldn't have the client-secret in the JS source but I don't believe it's doing any harm (since the only alternative is to have a blank client-secret which isn't any more secure). You're not unsafe (as the spec allows for this kind of thing) but you'd be safer using the authorization code flow (which would require a little work in the jhipster implementation) or to have a light server proxy add the client-secret to the request to the "token" endpoint rather than from the JS directly. Server to server communication (e.g. via a proxy) keeps secrets away from the view of the browser.

see this post for a nice discussion of the pitfalls of a JS-only client with oauth2: http://alexbilbie.com/2014/11/oauth-and-javascript/

here's an example of using oauth2 with angularjs and spring over a proxy: https://spring.io/blog/2015/02/03/sso-with-oauth2-angular-js-and-spring-security-part-v

这篇关于jhipster oauth2客户端机密的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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