Мы используем 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
Так настроен раздел OAuth 2.0 в Cognito: