AWS Cognito更改密码.Net Core 3 MVC

时间:2020-04-02 20:30:55

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

我们将AWS Cognito用于用户帐户并使用其托管登录表单。今天,我意识到在Cognito托管的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部分的方式:

enter image description here

1 个答案:

答案 0 :(得分:0)

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

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