我已经创建了一个 WebApi 和一个 Cordova 应用程序。 我正在使用 HTTP 请求在 Cordova 应用程序和 WebAPI 之间进行通信。 在 WebAPI 中,我实现了 OAuth Bearer Token Generation。
public void ConfigureOAuth(IAppBuilder app)
{
var oAuthServerOptions = new OAuthAuthorizationServerOptions
{
AllowInsecureHttp = true,
TokenEndpointPath = new PathString("/token"),
AccessTokenExpireTimeSpan = TimeSpan.FromDays(1),
Provider = new SimpleAuthorizationServerProvider(new UserService(new Repository<User>(new RabbitApiObjectContext()), new EncryptionService()))
};
// Token Generation
app.UseOAuthAuthorizationServer(oAuthServerOptions);
app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions());
}
这是在 SimpleAuthorizationServerProvider
实现中
public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
{
context.OwinContext.Response.Headers.Add("Access-Control-Allow-Origin", new[] { "*" });
// A little hack. context.UserName contains the email
var user = await _userService.GetUserByEmailAndPassword(context.UserName, context.Password);
if (user == null)
{
context.SetError("invalid_grant", "Wrong email or password.");
return;
}
var identity = new ClaimsIdentity(context.Options.AuthenticationType);
identity.AddClaim(new Claim("sub", context.UserName));
identity.AddClaim(new Claim("role", "user"));
context.Validated(identity);
}
从 Cordova 应用程序向 API 成功登录请求后,我收到以下 JSON
{"access_token":"some token","token_type":"bearer","expires_in":86399}
问题是,我需要有关用户的更多信息。例如,我在数据库中有一个 UserGuid 字段,我想在登录成功时将它发送到 Cordova 应用程序,并在以后的其他请求中使用它。除了 "access_token"、"token_type"
和 "expires_in"
之外,我能否包含其他信息以返回给客户端?如果没有,如何根据access_token
获取API中的用户?
编辑:
我认为我找到了解决方法。
我在 GrantResourceOwnerCredentials
identity.AddClaim(new Claim(ClaimTypes.Name, user.UserGuid.ToString()));
然后,我像这样访问 Controller 内的 GUID:User.Identity.Name
我还可以添加具有自定义名称的 guid identity.AddClaim(new Claim("guid", user.UserGuid.ToString()));
我仍然很想知道是否有一种方法可以使用不记名 token JSON 将更多数据返回给客户端。
最佳答案
您可以根据需要添加任意数量的声明。
您可以从 System.Security.Claims
添加标准声明集或创建您自己的声明集。
声明将在您的 token 中加密,因此只能从资源服务器访问它们。
如果您希望您的客户端能够读取您 token 的扩展属性,您还有另一种选择:AuthenticationProperties
。
假设您要添加一些内容以便您的客户可以访问。这是要走的路:
var props = new AuthenticationProperties(new Dictionary<string, string>
{
{
"surname", "Smith"
},
{
"age", "20"
},
{
"gender", "Male"
}
});
现在您可以使用上面添加的属性创建工单:
var ticket = new AuthenticationTicket(identity, props);
context.Validated(ticket);
这是您的客户端将获取的结果:
.expires: "Tue, 14 Oct 2014 20:42:52 GMT"
.issued: "Tue, 14 Oct 2014 20:12:52 GMT"
access_token: "blahblahblah"
expires_in: 1799
age: "20"
gender: "Male"
surname: "Smith"
token_type: "bearer"
另一方面,如果您添加声明,您将能够在 API Controller 的资源服务器中读取它们:
public IHttpActionResult Get()
{
ClaimsPrincipal principal = Request.GetRequestContext().Principal as ClaimsPrincipal;
return Ok();
}
您的 ClaimsPrincipal
将包含您在此处添加的新声明的 guid
:
identity.AddClaim(new Claim("guid", user.UserGuid.ToString()));
如果您想了解更多关于 owin、不记名 token 和 web api 的信息,这里有一个非常好的教程 here还有这个article将帮助您掌握Authorization Server 和Resource Server 背后的所有概念。
更新:
您可以找到一个工作示例 here .这是一个 Web Api + Owin 自托管。
这里不涉及数据库。
客户端是一个控制台应用程序(还有一个 html + JavaScript 示例),它调用 Web Api 传递凭据。
正如 Taiseer 所建议的,您需要覆盖 TokenEndpoint
:
public override Task TokenEndpoint(OAuthTokenEndpointContext context)
{
foreach (KeyValuePair<string, string> property in context.Properties.Dictionary)
{
context.AdditionalResponseParameters.Add(property.Key, property.Value);
}
return Task.FromResult<object>(null);
}
从解决方案 -> 属性中启用“多个启动项目”,您可以立即运行它。
关于c# - 在 WebApi 中使用 OAuth Bearer Tokens Generation 和 Owin 将更多信息返回给客户端,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26357054/