在我的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?
答案 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 。 第二个解决方案需要从用户上下文中获取用户并检查其存在。
谢谢。