Oauth 2.0 使用DotNetOpenAuth中用户名密码授予中的刷新令牌请求新访问令牌

Oauth 2.0 使用DotNetOpenAuth中用户名密码授予中的刷新令牌请求新访问令牌,oauth-2.0,token,dotnetopenauth,Oauth 2.0,Token,Dotnetopenauth,我正在尝试使用DotNetOpenAuth实现OAuth2授权服务器。客户端是基于JavaScript的,因此无法保存任何机密。这与另一个框架的问题完全相同 客户端使用以下参数请求(针对令牌端点)access\u-token和refresh\u-token: 授权类型:密码 用户名:foo 密码:栏 这确实有效。现在我想使用刷新\u令牌并使用以下参数对令牌端点发出请求: 授权类型:刷新令牌 刷新\u令牌:ABCDEF 我的回应如下: {"error":"invalid_client","

我正在尝试使用
DotNetOpenAuth
实现OAuth2授权服务器。客户端是基于JavaScript的,因此无法保存任何机密。这与另一个框架的问题完全相同

客户端使用以下参数请求(针对令牌端点)
access\u-token
refresh\u-token

  • 授权类型:密码
  • 用户名:foo
  • 密码:栏
这确实有效。现在我想使用
刷新\u令牌
并使用以下参数对令牌端点发出请求:

  • 授权类型:刷新令牌
  • 刷新\u令牌:ABCDEF
我的回应如下:

{"error":"invalid_client","error_description":"The client secret was incorrect."}
这是有意义的(至少有些意义),因为:

因为刷新令牌通常是用于 请求其他访问令牌时,刷新令牌将绑定到 向其发出该证书的客户机。如果客户端类型是机密的或 已向客户端颁发客户端凭据(或为其分配其他凭据) 身份验证要求),客户端必须通过 授权服务器,如第3.2.1节所述

如果我这样更改我的请求:

  • 授权类型:刷新令牌
  • 刷新\u令牌:ABCDEF
  • 客户id:我的客户
  • 客户机密:客户机密
问题是我的客户端不应该是机密的(因为它毕竟是客户端JavaScript)

这就是客户机的定义方式:

New ClientDescription(ApiKey, New Uri(allowedCallback), ClientType.Public)
我搜索了DotNetOpenAuth源代码,发现没有使用
ClientType
。在我看来,它似乎根本没有被使用

也不可能设置空的客户端密码,因为DotNetOpenAuth源代码会主动对此进行检查(
ClientAuthenticationModules.cs
):

如果我看一下
MessageValidationBindingElement.cs

                if (!string.IsNullOrEmpty(clientSecret)) {
                    if (client.IsValidClientSecret(clientSecret)) {
                        return ClientAuthenticationResult.ClientAuthenticated;
                    } else { // invalid client secret
                        return ClientAuthenticationResult.ClientAuthenticationRejected;
                    }
                } else { // no client secret provided
                    return ClientAuthenticationResult.ClientIdNotAuthenticated;
                }
        if (authenticatedClientRequest != null) {
            string clientIdentifier;
            var result = this.clientAuthenticationModule.TryAuthenticateClient(this.AuthServerChannel.AuthorizationServer, authenticatedClientRequest, out clientIdentifier);
            switch (result) {
                case ClientAuthenticationResult.ClientAuthenticated:
                    break;
                case ClientAuthenticationResult.NoAuthenticationRecognized:
                case ClientAuthenticationResult.ClientIdNotAuthenticated:
                    // The only grant type that allows no client credentials is the resource owner credentials grant.
                    AuthServerUtilities.TokenEndpointVerify(resourceOwnerPasswordCarrier != null, accessTokenRequest, Protocol.AccessTokenRequestErrorCodes.InvalidClient, this.clientAuthenticationModule, AuthServerStrings.ClientSecretMismatch);
                    break;
                default:
                    AuthServerUtilities.TokenEndpointVerify(false, accessTokenRequest, Protocol.AccessTokenRequestErrorCodes.InvalidClient, this.clientAuthenticationModule, AuthServerStrings.ClientSecretMismatch);
                    break;
            }
特别是注释-唯一不允许客户端凭据的授予类型是资源所有者凭据授予。让我想知道。这是否意味着在我的场景中,JS客户端应该发送用户名/密码?否这将引发以下异常:

AccessTokenResourceOwnerPasswordCredentialsRequest parameter 'grant_type' to have value 'password' but had 'refresh_token' instead.
这对我来说没关系,因为我不想让客户保留密码

所以我的问题是:

  • 我是否理解了密码授权、刷新令牌方案的根本错误
  • 正如我在JS客户端中看到的,
    client\u id
    是公共知识,因此它不起任何安全作用。我说得对吗
  • 将DotNetOpenAuth更改为使用
    ClientType.Public
    ,有意义吗
  • 如果我只使用
    client\u id
    client\u secret
    作为非secret会有什么不同吗?例如,仅提供虚拟值?安全问题是什么