使用两种方式为 web api 2 中的用户创建不记名令牌与 owin 上下文
Use two way to create bearer token for users in web api 2 with owin context
我有一个 Asp.net web api 2 项目。在这个项目中,我使用 OWIN 身份验证。
我有两种用户。
一类是用用户名和密码登录,一类是手机号和一个四字词登录
我希望这两个用户都去地址 /token 获取他们的令牌,到目前为止我的实现是这样的:
这是启动 class :
var provider = new AuthorizationServerProvider();
var options = new OAuthAuthorizationServerOptions()
{
AllowInsecureHttp = true,
TokenEndpointPath = new PathString("/token"),
AccessTokenExpireTimeSpan = TimeSpan.FromDays(1),
Provider = provider
};
public class AuthorizationServerProvider : OAuthAuthorizationServerProvider
{
public override async Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context)
{
context.Validated();
}
public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
{
var identity = new ClaimsIdentity(context.Options.AuthenticationType);
using (DbContext dbContext = new DbContext ())
{
var user = dbContext.User
.Where(a => a.UserName == context.UserName)
.Where(a => a.Password == context.Password)
.Select(a => new UserClaim
{
Id = a.Id,
UserName = a.UserName,
FirstName = a.FirstName,
LastName = a.LastName,
Roles = a.UserInRoles.Select(w => w.Role.Id).ToList()
}).FirstOrDefault();
if (user == null)
{
context.SetError("invalid grant", "Provided username and password is incorrect.");
return;
}
identity.AddUserClaim(user);
context.Validated(identity);
return;
}
}
}
此解决方案适用于想用用户名登录的用户,但是想用手机号登录的用户怎么办?
您需要提供两个 OAuthAuthorizationServerOptions
实例,一个用于使用用户名和密码进行授权,一个用于手机号码和代码,然后通过授权中间件将这两个选项添加到您的 owin 管道中。
public partial class Startup
{
public void Configuration(IAppBuilder app)
{
// rest of your code
var userAndPasswordOptions = new OAuthAuthorizationServerOptions(){ ... };
var mobileAndCodeOptions = new OAuthAuthorizationServerOptions(){ ... };
app.UseOAuthAuthorizationServer(userAndPasswordOptions);
app.UseOAuthAuthorizationServer(mobileAndCodeOptions);
// rest of your code
}
}
但您应该知道在这种情况下,这两个提供商对不同的请求端点做出响应。
如果您需要一个端点来提供两种类型的授权,您可以在 OAuthAuthorizationServerProvider
中更改 GrantResourceOwnerCredentials
方法。
public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
{
var identity = new ClaimsIdentity(context.Options.AuthenticationType);
var form = await context.Request.ReadFormAsync().Result;
if (form["type"] == "mobile")
{
//validate mobileNumber and code
}
else
{
//validate username and password
}
identity.AddUserClaim(user);
context.Validated(identity);
return;
}
我有一个 Asp.net web api 2 项目。在这个项目中,我使用 OWIN 身份验证。 我有两种用户。
一类是用用户名和密码登录,一类是手机号和一个四字词登录
我希望这两个用户都去地址 /token 获取他们的令牌,到目前为止我的实现是这样的:
这是启动 class :
var provider = new AuthorizationServerProvider();
var options = new OAuthAuthorizationServerOptions()
{
AllowInsecureHttp = true,
TokenEndpointPath = new PathString("/token"),
AccessTokenExpireTimeSpan = TimeSpan.FromDays(1),
Provider = provider
};
public class AuthorizationServerProvider : OAuthAuthorizationServerProvider
{
public override async Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context)
{
context.Validated();
}
public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
{
var identity = new ClaimsIdentity(context.Options.AuthenticationType);
using (DbContext dbContext = new DbContext ())
{
var user = dbContext.User
.Where(a => a.UserName == context.UserName)
.Where(a => a.Password == context.Password)
.Select(a => new UserClaim
{
Id = a.Id,
UserName = a.UserName,
FirstName = a.FirstName,
LastName = a.LastName,
Roles = a.UserInRoles.Select(w => w.Role.Id).ToList()
}).FirstOrDefault();
if (user == null)
{
context.SetError("invalid grant", "Provided username and password is incorrect.");
return;
}
identity.AddUserClaim(user);
context.Validated(identity);
return;
}
}
}
此解决方案适用于想用用户名登录的用户,但是想用手机号登录的用户怎么办?
您需要提供两个 OAuthAuthorizationServerOptions
实例,一个用于使用用户名和密码进行授权,一个用于手机号码和代码,然后通过授权中间件将这两个选项添加到您的 owin 管道中。
public partial class Startup
{
public void Configuration(IAppBuilder app)
{
// rest of your code
var userAndPasswordOptions = new OAuthAuthorizationServerOptions(){ ... };
var mobileAndCodeOptions = new OAuthAuthorizationServerOptions(){ ... };
app.UseOAuthAuthorizationServer(userAndPasswordOptions);
app.UseOAuthAuthorizationServer(mobileAndCodeOptions);
// rest of your code
}
}
但您应该知道在这种情况下,这两个提供商对不同的请求端点做出响应。
如果您需要一个端点来提供两种类型的授权,您可以在 OAuthAuthorizationServerProvider
中更改 GrantResourceOwnerCredentials
方法。
public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
{
var identity = new ClaimsIdentity(context.Options.AuthenticationType);
var form = await context.Request.ReadFormAsync().Result;
if (form["type"] == "mobile")
{
//validate mobileNumber and code
}
else
{
//validate username and password
}
identity.AddUserClaim(user);
context.Validated(identity);
return;
}