Как получить имя пользователя в методе ValidateClientAuthentication - PullRequest
0 голосов
/ 05 июля 2019

В моем приложении webAPI я использовал Resource Owner Password Credentials Grant для аутентификации.Текущий код работает нормально с именем пользователя и паролем.

Теперь приложение включает в себя мультитенанта, поэтому я добавил детали 'clientId' в таблицу пользователей.В любом случае данные клиента находятся в другом облаке, мы можем вызвать этот API для проверки клиента, передав clientId и пароль.

Для реализации этого я использовал метод ValidateClientAuthentication для проверки клиента и метод GrantResourceOwnerCredentials для проверкипользователь.Это тоже хорошо.

Проблема: По сути, мне также нужно поддерживать старых клиентов, чтобы у них не было данных клиента.Поэтому, если у пользователя есть clientId, нам нужно проверить клиента, в противном случае только подтвердить пользователя.

Реализация:

        public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
    {
        var userManager = context.OwinContext.GetUserManager<ApplicationUserManager>();
        ApplicationUser user = await userManager.FindAsync(context.UserName, context.Password);

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


        ClaimsIdentity oAuthIdentity = await user.GenerateUserIdentityAsync(userManager,
           OAuthDefaults.AuthenticationType);
        ClaimsIdentity cookiesIdentity = await user.GenerateUserIdentityAsync(userManager,
            CookieAuthenticationDefaults.AuthenticationType);


        AuthenticationProperties properties = CreateProperties(user.UserName,context.ClientId);
        AuthenticationTicket ticket = new AuthenticationTicket(oAuthIdentity, properties);
        context.Validated(ticket);
        context.Request.Context.Authentication.SignIn(cookiesIdentity);
    }

    public override async Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context)
    {
        string clientId;
        string clientSecret;
        context.TryGetFormCredentials(out clientId, out clientSecret);

        TenantCloud clientAPI = new TenantCloud();
        context.TryGetFormCredentials(out clientId, out clientSecret);

        if (clientId != null || clientSecret != null)
        {
            var tenantResponseJson = await clientAPI.AuthorizeTenant(clientId, clientSecret).ConfigureAwait(false);
            if (tenantResponseJson == null || (tenantResponseJson != null && tenantResponseJson.AccessToken == null))
            {
                context.Rejected();
                return;
            }
        }
        context.Validated();
        return;
    }

Текущий код работает правильно, если пользователь передает клиентподробности.Но я хочу подтвердить, есть ли у пользователя клиент или нет.Если у пользователя есть clientId, он должен подтвердить или вернуть ошибку.

Чтобы сделать это, любой вариант получить имя пользователя из запроса, чтобы я мог получить соответствующего пользователя и проверить, есть ли у пользователя clientId или нет?

1 Ответ

0 голосов
/ 05 июля 2019

Я получил решение двумя способами.

Решение 1:

Я могу проверить context.ClientId не равен NULL, если у пользователя есть идентификатор клиента.Обновление, как показано ниже:

        public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
    {
        var userManager = context.OwinContext.GetUserManager<ApplicationUserManager>();
        ApplicationUser user = await userManager.FindAsync(context.UserName, context.Password);
        if (user == null || user.IsDeleted)
        {
            context.SetError("invalid_grant", "The user name or password is incorrect.");
            return;
        }
        //Ensure that user has client/ tenant. If user have tenant and the tenant is not passed, set the context as rejected.
        if (!string.IsNullOrEmpty(user.ClientId) && string.IsNullOrEmpty(context.ClientId))
        {
            context.SetError("invalid_grant", "The client credentials are incorrect.");
            return;
        }

        ClaimsIdentity oAuthIdentity = await user.GenerateUserIdentityAsync(userManager,
           OAuthDefaults.AuthenticationType);
        ClaimsIdentity cookiesIdentity = await user.GenerateUserIdentityAsync(userManager,
            CookieAuthenticationDefaults.AuthenticationType);


        AuthenticationProperties properties = CreateProperties(user.UserName, !string.IsNullOrEmpty(user.ClientId) ? context.ClientId : string.Empty);
        AuthenticationTicket ticket = new AuthenticationTicket(oAuthIdentity, properties);
        context.Validated(ticket);
        context.Request.Context.Authentication.SignIn(cookiesIdentity);
    }

Решение 2:

Это точно ответ на вопрос.Я могу получить userId, используя context.Parameters в самом методе ValidateClientAuthentication.

var username = context.Parameters.Get("username");

Здесь я могу получить пользователя (здесь не проверяется) и проверить, есть ли у пользователя идентификатор клиента.Если существует, мне нужно проверить клиента, в противном случае отклонено.

Я использовал решение 1 для простоты .Второе решение должно взять пользователя из контекста owin и проверить его существование.

Спасибо.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...