Owin oauth посылает дополнительные параметры

Я уверен, что это возможно, но не уверен, как этого добиться. У меня есть реализация OWIN OAUTH, которая в настоящее время принимает пользователей Username и Password и проверяет их подлинность на базе базы данных. Я хотел бы расширить это, чтобы перейти в SmartCard Uid для поддержки единого входа с помощью смарт-карты.

Могу ли я передать дополнительные параметры в логин OWIN, и если да, то как? Основная предпосылка заключается в том, что пользователь может войти в систему с комбинацией имени пользователя и пароля или с помощью смарт-карты uid (при передаче SmartCard uid и найденной в базе данных, тогда приложение будет регистрировать пользователя)

В настоящее время я перехожу в username, password и grant_type, и я хотел бы добавить uid в этот список и выбрать его в my AuthorizationServiceProvider.

Я могу видеть username, password и ClientId на OAuthGrantResourceOwnerCredentialsContext, но я не вижу других свойств, которые бы поддерживали то, что я пытаюсь достичь.

Это то, что у меня есть у моего поставщика услуг

    public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
    {
        context.OwinContext.Response.Headers.Add("Access-Control-Allow-Origin", new[] { "*" });

        var user = await this._userService.FindUser(context.UserName, context.Password);

        if (user == null)
        {
            context.SetError("invalid_grant", "The user name or password is incorrect.");
            return;
        }

        var identity = new ClaimsIdentity(context.Options.AuthenticationType);
        identity.AddClaim(new Claim(ClaimTypes.Sid, user.Id.ToString()));
        identity.AddClaim(new Claim(ClaimTypes.Role, "user"));
        identity.AddClaim(new Claim("sub", context.UserName));

        var secretKeyBytes = Encoding.UTF8.GetBytes(user.PasswordHash);
        var props =
            new AuthenticationProperties(
                new Dictionary<string, string>
                    {
                        { "dm:appid", user.Id.ToString() },
                        { "dm:apikey", Convert.ToBase64String(secretKeyBytes) }
                    });

        var ticket = new AuthenticationTicket(identity, props);
        context.Validated(ticket);
    }

Я хочу, чтобы иметь возможность получить Uid из контекста, но не могу все равно добиться этого, любая помощь очень ценится.

Ответ 1

Вы должны реализовать ValidateClientAuthentication, если вы этого еще не сделали.

Это место, где вы должны проверить свой клиент. В этих методах вы сделаете какую-то проверку своего клиента и установите объекты/переменную, которые можно прочитать в GrantResourceOwnerCredentials.

Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context)

получает OAuthValidateClientAuthenticationContext, который содержит дополнительное поле вашей передачи при отправке POST на ваш сервер авторизации.

enter image description here

На рисунке выше добавлен дополнительный параметр uid в 4-й позиции.

Прежде чем проверить свой контекст:

context.Validated(clientId);

вы можете установить свою переменную/объект:

string uid = context.Parameters.Where(f => f.Key == "uid").Select(f => f.Value).SingleOrDefault()[0];
context.OwinContext.Set<string>("SmartCard", uid);

Теперь в вашем GrantResourceOwnerCredentials вы можете просто прочитать значение и использовать его:

string uid = context.OwinContext.Get<string>("SmartCard");

Если вы хотите узнать больше, вы можете посмотреть этот репозиторий github где я передаю объект:

context.OwinContext.Set<ApplicationClient>("oauth:client", client);

Если вы загрузите все решение, вы можете протестировать его с помощью javascript/jquery client.