【问题标题】:AWS Cognito Change Password .Net Core 3 MVCAWS Cognito 更改密码 .Net Core 3 MVC
【发布时间】:2020-04-02 20:30:55
【问题描述】:

我们将 AWS Cognito 用于用户账户并使用他们托管的登录表单。今天我意识到在 Cognito Hosted Web UI 上的任何地方都没有“更改密码”功能。这是真的?如果是,我需要弄清楚如何构建更改密码表单。

该应用内置于 .NET Core 3.1 中,我添加了 AWSSDK.CognitoIdentityProvider NuGet 包。

在用户登录 Cognito 并通过 OpenIdConnect 重定向回我的应用程序后,我获得了访问令牌。在我的Startup.cs 中,我在.AddOpenIdConnect() 中有这段代码,它在ConfigureServices() 中,我认为这是给我一个用户访问令牌:

options.Events = new OpenIdConnectEvents()
{
    OnTokenValidated = context =>
    {
        // Access Token
        var accessToken = context.SecurityToken.RawData;

        var option = new Microsoft.AspNetCore.Http.CookieOptions();

        option.Expires = new DateTimeOffset(context.SecurityToken.ValidTo);
        context.HttpContext.Response.Cookies.Append("CognitoAccessToken", accessToken, option);

        return Task.CompletedTask;
    },
}

然后在另一个请求中,我得到相同的令牌并将其传递给ChangePasswordAsync

var cognitoClient = new Amazon.CognitoIdentityProvider.AmazonCognitoIdentityProviderClient("admin-level-access-key-id", "admin-level-secret-access-key");

var testClientWorks = await cognitoClient.DescribeUserPoolAsync(new Amazon.CognitoIdentityProvider.Model.DescribeUserPoolRequest { UserPoolId = "...my pool id..." });

var token = HttpContext.Request.Cookies["CognitoAccessToken"].ToString();
var response = await cognitoClient.ChangePasswordAsync(new Amazon.CognitoIdentityProvider.Model.ChangePasswordRequest
{
    AccessToken = token,
    PreviousPassword = "oldpassword",
    ProposedPassword = "Test1234$"
});

DescribeUserPoolAsync 的调用有效,所以我知道cognitoClient 的凭据是有效的。但是对ChangePasswordAsync 的调用失败并出现错误“无效的访问令牌”。

那么,如果我在他们登录时获得的访问令牌不好,我在哪里可以得到一个有效的?

编辑:

所以事实证明我有一个 ID 令牌而不是一个访问令牌。我认为这是因为我如何配置 OpenIdConnect。将options.ResponseType 更改为token 如下所示会导致错误:Exception: OpenIdConnectAuthenticationHandler: message.State is null or empty

options.SignInScheme = "Cookies";
options.Authority = $"https://cognito-idp.{awsCognitoRegion}.amazonaws.com/{awsCognitoPoolId}";
options.RequireHttpsMetadata = true;
options.ClientId = awsCognitoClientId;
options.ClientSecret = awsCognitoSecret;
//options.ResponseType = "code"; //what I was using before
options.ResponseType = "token";
options.UsePkce = true;
//options.Scope.Add("profile");
//options.Scope.Add("offline_access"); //results in invalid scope error
options.Scope.Add("openid");
//options.Scope.Add("aws.cognito.signin.user.admin");
options.SaveTokens = true;

////Tell .Net Core identity where to find the "name"
options.TokenValidationParameters.NameClaimType = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress";
options.TokenValidationParameters.AuthenticationType = IdentityConstants.ApplicationScheme;
////options.TokenValidationParameters.NameClaimType = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier";

options.GetClaimsFromUserInfoEndpoint = true;
options.ClaimActions.Clear(); //fixes something in .NET Core

这是在 Cognito 中配置 OAuth 2.0 部分的方式:

【问题讨论】:

  • 您能否打印访问令牌以确保它确实是 JWT 令牌?尝试在 jwt.io 上对其进行解码。在其他字段中,它应该有"token_use": "access"
  • 它确实在 jwt.io 解码,但只有 "token_use": "id"。那么,这是我需要请求的不同范围(并且可能在 AWS Cognito 中打开)吗?
  • 或者有没有办法使用 id 令牌从CognitoIdentityProvider 请求访问令牌?
  • @MaxIvanov 我在原帖中添加了更多信息。
  • 对于服务器端应用程序,您应该使用code oauth 流,因为它更安全。该代码用于交换 ID Token、Access Token 和 Refresh Token。因此,如果您的代码中有 ID 令牌,我很确定也必须有访问令牌。抱歉,我对 .NET 一无所知,因此无法提供除此之外的代码。

标签: c# asp.net-mvc .net-core amazon-cognito


【解决方案1】:

事实证明,令牌被设置在幕后某处。因此,您可以在登录后通过以下方式请求它们:

var accessToken = await HttpContext.GetTokenAsync(OpenIdConnectParameterNames.AccessToken);
var refreshToken = await HttpContext.GetTokenAsync(OpenIdConnectParameterNames.RefreshToken);
var idToken = await HttpContext.GetTokenAsync(OpenIdConnectParameterNames.IdToken);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-06-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-08-13
    • 1970-01-01
    相关资源
    最近更新 更多