在WebApi中使用OAuth Bearer Tokens Generation和Owin返回更多信息给客户端

我创build了一个WebApi和一个Cordova应用程序。 我正在使用http请求在Cordova应用程序和WebApi之间进行通信。 在WebApi中,我实现了OAuth承载令牌生成。

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应用程序成功loginAPI后,我收到以下JSON

 {"access_token":"some token","token_type":"bearer","expires_in":86399} 

问题是,我需要更多关于用户的信息。 例如,我在数据库中有一个UserGuid字段,我想在login成功时将它发送给Cordova应用程序,稍后在其他请求中使用它。 除了"access_token", "token_type""expires_in"是否还可以包含返回给客户端的其他信息? 如果不是的话,我怎样才能获得基于access_token API的用户?


编辑:

我认为我find了一个解决方法。 我在GrantResourceOwnerCredentials添加了以下代码

 identity.AddClaim(new Claim(ClaimTypes.Name, user.UserGuid.ToString())); 

之后我访问我的控制器里面的guid,像这样: User.Identity.Name

我也可以添加一个自定义名称identity.AddClaim(new Claim("guid", user.UserGuid.ToString()));

我仍然有兴趣知道是否有一种方法可以使用不记名令牌JSON将更多数据返回给客户端。

您可以根据需要添加尽可能多的索赔。
您可以从System.Security.Claims添加标准的声明集或创build自己的声明。
索赔将在您的令牌中进行encryption,因此只能从资源服务器访问。

如果您希望您的客户端能够读取令牌的扩展属性,则可以使用另一个选项: AuthenticationProperties

比方说,你想添加一些东西,让你的客户端可以访问。 这是要走的路:

 var props = new AuthenticationProperties(new Dictionary<string, string> { { "surname", "Smith" }, { "age", "20" }, { "gender", "Male" } }); 

现在,您可以使用上面添加的属性创build票证:

 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控制器的资源服务器中读取它们:

 public IHttpActionResult Get() { ClaimsPrincipal principal = Request.GetRequestContext().Principal as ClaimsPrincipal; return Ok(); } 

您的ClaimsPrincipal将包含您在此处添加的新索赔的guid

 identity.AddClaim(new Claim("guid", user.UserGuid.ToString())); 

如果您想了解更多关于owin,不记名令牌和web api的信息,这里有一个非常好的教程,这篇文章将帮助您掌握授权服务器资源服务器背后的所有概念。

更新

你可以在这里find一个工作的例子。 这是一个Web Api + Owin自己托pipe的。
这里没有涉及数据库。 客户端是一个控制台应用程序(还有一个html + JavaScript样本),它调用Web Api传递凭据。

正如Taiseerbuild议的那样,您需要重写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); } 

从解决scheme – >属性启用'多个启动项目',你可以马上运行它。

我的build议是不添加额外的声明,如果不需要的话,因为会增加令牌的大小,你会继续发送每个请求。 正如LeftyXbuild议将它们添加为属性,但确保您重写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); } 

您可以查看我的回购在这里完整的例子。 希望它会有所帮助。

Interesting Posts