Как изменить идентификатор AntiForgeryToken по умолчанию в ядре asp.net mvc? - PullRequest
0 голосов
/ 26 марта 2019

Я пытаюсь использовать AWS Cognito для моей аутентификации в MVC-приложении .Net Core.

Вход в систему работает нормально, но ни одна из моих форм в представлениях не работает, все они выдают ошибку о моих утвержденияхне содержит «Name» -Claim.

Я пытался добавить заявку-имя вручную, но все равно выдает ошибки.

Есть идеи, как настроить это в ядре .net?

Сообщение об ошибке:

InvalidOperationException: Предоставленный идентификатор типа 'System.Security.Claims.ClaimsIdentity' помечен IsAuthenticated = true, но не имеет значения для имени.По умолчанию система защиты от подделки требует, чтобы все идентифицированные личности имели уникальное имя.Если невозможно предоставить уникальное имя для этого идентификатора, рассмотрите возможность расширения IAntiforgeryAdditionalDataProvider путем переопределения DefaultAntiforgeryAdditionalDataProvider или пользовательского типа, который может предоставить некоторую форму уникального идентификатора для текущего пользователя.

Startup-config:

services.AddAuthentication(options =>
            {
                //Sets Default Scheme.
                options.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme;
                options.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;

                //Must match the string for AddOAuth to set OAuth as default Challenge Scheme.
                options.DefaultChallengeScheme = "Cognito";
            })
               .AddCookie()
               .AddOAuth("Cognito", options =>
               {
                   options.ClientId = Configuration["Authentication:Cognito:ClientId"];
                   options.ClientSecret = Configuration["Authentication:Cognito:Secret"];
                   options.CallbackPath = new PathString("/sign-in");
                   options.AuthorizationEndpoint = "https://myauth.auth.eu-west-1.amazoncognito.com/oauth2/authorize";
                   options.TokenEndpoint = "https://myauth.auth.eu-west-1.amazoncognito.com/oauth2/token";
                   options.SaveTokens = true;
                   options.ClaimsIssuer = "https://cognito-idp.eu-west-1.amazonaws.com/ID";

                   options.Events = new OAuthEvents
                   {
                        //Adds Cognito id_token to Claims.
                        OnCreatingTicket = OnCreatingTicket
                   };
               });

Добавление имени-идентификатора вручную:

private static Task OnCreatingTicket(OAuthCreatingTicketContext context)
        {
            var handler = new JwtSecurityTokenHandler();

            //Cognito stores user information and Claims in the id_token.
            var idToken = context.TokenResponse.Response["id_token"];
            var jwtToken = handler.ReadJwtToken(idToken.ToString());

            var appIdentity = new ClaimsIdentity(jwtToken.Claims);
            foreach (var item in appIdentity.Claims)
            {
                if (item.Type == "sub")
                { 
                    var name = new Claim("http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier", item.Value);
                    var name2 = new Claim("http://schemas.microsoft.com/accesscontrolservice/2010/07/claims/identityprovider", item.Value);
                    appIdentity.AddClaim(name);
                    appIdentity.AddClaim(name2);
                break;
                }
            }

            context.Principal.AddIdentity(appIdentity);
            return Task.CompletedTask;
        }

Ответы [ 2 ]

0 голосов
/ 11 апреля 2019

Просто добавление имени-идентификатора не сработало. После долгих поисков это нужно сделать:

  1. Добавить имя-идентификатор к JWT
  2. указать имя провайдера при запуске:

    var appIdentity = new ClaimsIdentity(jwtToken.Claims, CookieAuthenticationDefaults.AuthenticationScheme);
    

После шага 2 это было решено.

Полный код:

    private static Task OnCreatingTicket(OAuthCreatingTicketContext context)
    {
        var handler = new JwtSecurityTokenHandler();

        var idToken = context.TokenResponse.Response["id_token"];
        var jwtToken = handler.ReadJwtToken(idToken.ToString());

        var appIdentity = new ClaimsIdentity(jwtToken.Claims, CookieAuthenticationDefaults.AuthenticationScheme);

        context.Principal.AddIdentity(appIdentity);

        return Task.CompletedTask;
    }
0 голосов
/ 27 марта 2019

Я полагаю, что идентификация, которую вы создаете вручную в методе OnCreatingTicket, игнорируется функцией защиты от подделки, поскольку она не считается аутентифицированной (см. источник на GitHub , в частности L51);Причина этого в том, что свойство IsAuthenticated зависит от того, что свойство AuthenticationType не является null или пустым (см. source на source.dot.net ).

Использование *Перегрузка конструктора 1011 * должна заставить систему защиты от подделки учитывать вашу пользовательскую идентификацию.

В качестве альтернативы, чтобы вообще не создавать пользовательский ClaimsIdentity, можно убедиться, что тот, который создан поставщиком аутентификации OAuth, содержитодна из тех претензий, которые по умолчанию ищутся с помощью DefaultClaimUidExtractor в методе GetUniqueIdentifierParameters:

...