【问题标题】:Do not receive refresh token with OpenIddict不使用 OpenIddict 接收刷新令牌
【发布时间】:2018-03-22 04:57:12
【问题描述】:

我有一个基于 .net core 2.0 的 web api 项目。

我几乎遵循了http://kevinchalet.com/2017/01/30/implementing-simple-token-authentication-in-aspnet-core-with-openiddict/ 上的非常好的例子。

为验证返回 SignIn() 结果的代码。方法如下:

if (request.IsPasswordGrantType())
{
    // (...)
    if (useraccount != null && useraccount.Failcount <= AppConstants.AuthMaxAllowedFailedLogin)
    {
        var identity = new ClaimsIdentity(OpenIdConnectServerDefaults.AuthenticationScheme, OpenIdConnectConstants.Claims.Name, OpenIdConnectConstants.Claims.Role);

        identity.AddClaim(OpenIdConnectConstants.Claims.Subject, AppConstants.AuthSubjectClaim, OpenIdConnectConstants.Destinations.AccessToken);
        identity.AddClaim(OpenIdConnectConstants.Claims.Name, useraccount.Username, OpenIdConnectConstants.Destinations.AccessToken);

        return SignIn(new ClaimsPrincipal(identity), OpenIdConnectServerDefaults.AuthenticationScheme);
    }
    // (...)
}

我的启动代码如下所示:

services.AddDbContext<DbContext>(options =>
{
    options.UseInMemoryDatabase(nameof(DbContext));
    options.UseOpenIddict();
});

services.AddOpenIddict(options =>
{
    options.AddEntityFrameworkCoreStores<DbContext>();
    options.AddMvcBinders();
    options.EnableTokenEndpoint(DcpConstants.ApiTokenRoute);
    options.AllowPasswordFlow();
    options.AllowRefreshTokenFlow();
    options.SetAccessTokenLifetime(TimeSpan.FromHours(1));
    options.SetRefreshTokenLifetime(TimeSpan.FromDays(1));
    options.DisableHttpsRequirement();
});

services.AddAuthentication(options =>
{
    options.DefaultScheme = OAuthValidationDefaults.AuthenticationScheme;
}).AddOAuthValidation();

现在,当我使用以下参数发送发布请求时:

username: foo@bar.com
password: myPassword
grant_type: password
scope: openid profile offline_access

我只收到范围、token_type、access_token、expires_in 和 id_token,没有 refresh_token。

我错过了什么?

【问题讨论】:

    标签: c# asp.net-core token refresh-token openiddict


    【解决方案1】:

    options.AllowPasswordFlow();

    刷新令牌不能与密码流一起使用,因为在此流中用户永远不会被重定向到身份验证服务器登录,so can’t directly authorize the application:

    如果应用程序使用用户名-密码 OAuth 身份验证流程,则不会发出刷新令牌,因为用户无法在此流程中授权应用程序。如果访问令牌过期,使用用户名-密码 OAuth 流程的应用程序必须重新对用户进行身份验证。

    【讨论】:

    • 值得注意的是,虽然 Salesforce 决定他们不想为密码流请求返回刷新令牌,但 OAuth2 规范绝对不禁止这样做:If the access token request is valid and authorized, the authorization server issues an access token and optional refresh tokentools.ietf.org/html/rfc6749#section-4.3.3
    • FWIW,我个人认为不返回带有密码流的刷新令牌是一个可怕的错误,因为它鼓励客户端应用程序通过存储用户名/密码来解决此限制,以检索新的访问令牌他们需要不必一次又一次地询问用户他/她的凭据(这从根本上是不好的)。
    【解决方案2】:

    OAuth2 规范绝对允许使用密码返回刷新令牌,因此 OpenIddict 完全支持。

    对于要由 OpenIddict 返回的刷新令牌,您必须在调用 SignIn 时授予特殊的 offline_access 范围。例如:

    if (request.IsPasswordGrantType())
    {
        // (...)
        if (useraccount != null && useraccount.Failcount <= AppConstants.AuthMaxAllowedFailedLogin)
        {
            var identity = new ClaimsIdentity(OpenIdConnectServerDefaults.AuthenticationScheme, OpenIdConnectConstants.Claims.Name, OpenIdConnectConstants.Claims.Role);
    
            identity.AddClaim(OpenIdConnectConstants.Claims.Subject, AppConstants.AuthSubjectClaim, OpenIdConnectConstants.Destinations.AccessToken);
            identity.AddClaim(OpenIdConnectConstants.Claims.Name, useraccount.Username, OpenIdConnectConstants.Destinations.AccessToken);
    
            var ticket = new AuthenticationTicket(
                new ClaimsPrincipal(identity),
                new AuthenticationProperties(),
                OpenIdConnectServerDefaults.AuthenticationScheme);
    
            // You have to grant the 'offline_access' scope to allow
            // OpenIddict to return a refresh token to the caller.
            ticket.SetScopes(OpenIdConnectConstants.Scopes.OfflineAccess);
    
            return SignIn(ticket.Principal, ticket.Properties, ticket.AuthenticationScheme);
        }
        // (...)
    }
    

    请注意,您还必须在控制器中处理 grant_type=refresh_token 请求。这是一个使用身份的示例:https://github.com/openiddict/openiddict-samples/blob/dev/samples/RefreshFlow/AuthorizationServer/Controllers/AuthorizationController.cs#L75-L109

    【讨论】:

      猜你喜欢
      • 2017-05-09
      • 2017-07-01
      • 1970-01-01
      • 1970-01-01
      • 2021-08-08
      • 2019-06-29
      • 1970-01-01
      • 2022-10-31
      • 2020-07-12
      相关资源
      最近更新 更多