如何在ValidateClientAuthentication方法中获取用户名

时间:2019-07-05 07:27:05

标签: oauth-2.0 asp.net-web-api2

在我的webAPI应用程序中,我使用Resource Owner Password Credentials Grant进行身份验证。当前代码可以使用用户名和密码正常工作。

现在,该应用程序包括多租户,因此我在用户表中添加了“ clientId”详细信息。无论如何,客户端详细信息位于另一个云中,我们可以通过传递clientId和密码来调用该api来验证客户端。

要实现此目的,我使用了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,则应验证或返回错误。

要执行此操作,是否可以从请求中获取用户名,以便我可以获取相应的用户并检查用户是否具有clientId?

1 个答案:

答案 0 :(得分:0)

我有两种解决方法。

解决方案1:

我可以检查context.ClientId不为null如果用户具有客户端ID。更新如下所示;

        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:

这正是问题的答案。我可以在context.Parameters方法本身中使用ValidateClientAuthentication获取userId。

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

在这里,我可以检索用户(此处未验证)并检查用户是否具有客户端ID。如果存在,我需要验证否则被拒绝的客户端。

为简单起见,我使用了解决方案1 ​​。 第二个解决方案需要从用户上下文中获取用户并检查其存在。

谢谢。