如何在 Web API 授权服务中将声明包含在我的 AuthTicket 中?
How do I get claims included in my AuthTicket in a Web API Auth Service?
我有一个带有身份验证服务的 Web API,对于 WPF 客户端,设置如下:
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
config.SuppressDefaultHostAuthentication();
config.Filters.Add(new HostAuthenticationFilter(OAuthDefaults.AuthenticationType));
...
}
}
和
public partial class Startup
{
public void ConfigureAuth(IAppBuilder app)
{
...
OAuthOptions = new OAuthAuthorizationServerOptions
{
TokenEndpointPath = new PathString("/Token"),
Provider = new ApplicationOAuthProvider(PublicClientId),
ApplicationCanDisplayErrors = true,
AuthorizeEndpointPath = new PathString("/api/Account/ExternalLogin"),
AccessTokenExpireTimeSpan = TimeSpan.FromDays(14),
AllowInsecureHttp = true, // TODO Make false to deploy
};
app.UseOAuthAuthorizationServer(OAuthOptions);
}
}
到目前为止,我只使用过 /Token
端点,因为它至少会授予我不记名令牌。我在身份验证成功时收到的票有签发日期和到期日期、不记名令牌和我的用户名。
如何获得用户的声明(可能还有角色)?有什么我可以在这里做的事情,或者我在验证后通过 API 缓慢地请求它们,并将它们和 Auth Ticket 聚合在 WPF 客户端的 Principal
对象中?
我是否可以在 WPF 应用程序中包含一些身份组件以帮助从令牌中提取声明,以及关于我应该如何执行此操作的任何建议?
我认为让客户端解密令牌是相当危险的。如果他们能做到这一点,恶意行为者就可以修改令牌和其中的声明。如果您不检查声明的有效性(可能是因为它们是由第三方提供的),那么这可能会导致特权升级和您的应用程序受到损害。
如果客户端应用程序需要声明 - 也许是 UI 布局,那么您可以将它们单独提供给令牌。一种方法是通过 ActionFilterAttribute 将声明写入自定义 http header。如果声明在这里被篡改,它只会影响客户端,因为您将在处理任何请求之前检查令牌中的安全声明。
public AddClaimsAttribute : System.Web.Http.Filters.ActionFilterAttribute
{
var principal = actionExecutedContext.ActionContext.RequestContext.Principal as ClaimsPrincipal;
if (principal != null)
{
var claims = principal.Claims.Select(x => x.Type + ":" + x.Value).ToList();
actionExecutedContext.Response.Content.Headers.Add("Claims",
String.Join(",", claims));
}
}
然后您的客户端只需要检查这个 header 并解析它。
这是一个基本示例,您可以将其格式化为 JSON 或添加一系列自定义 headers "IsAdmin"、"IsEditingUser" 等
因为它是一个过滤器,所以您可以将其全局应用于每个请求、控制器上的每个操作或您需要的特定操作。
您可以通过在令牌响应中添加用户角色轻松实现此目的。为此,您必须在 ApplicationOAuthProvider.cs class 中更新方法 CreateProperties
public static AuthenticationProperties CreateProperties(User user)
{
//get only roles ids
//to do: retrieve user roles names
var roles = string.Join(",", user.Roles.Select(t => t.RoleId).ToArray());
//expose phone in response
var phone = user.PhoneNumber;
IDictionary<string, string> data = new Dictionary<string, string>
{
{ "userName", user.UserName },
{ "userId", user.Id },
{ "roles", roles},
{ "phone", phone}
};
return new AuthenticationProperties(data);
}
您可以在邮递员响应中看到 3 个新属性:userId、roles 和 phone。添加新属性时请注意空值。
我有一个带有身份验证服务的 Web API,对于 WPF 客户端,设置如下:
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
config.SuppressDefaultHostAuthentication();
config.Filters.Add(new HostAuthenticationFilter(OAuthDefaults.AuthenticationType));
...
}
}
和
public partial class Startup
{
public void ConfigureAuth(IAppBuilder app)
{
...
OAuthOptions = new OAuthAuthorizationServerOptions
{
TokenEndpointPath = new PathString("/Token"),
Provider = new ApplicationOAuthProvider(PublicClientId),
ApplicationCanDisplayErrors = true,
AuthorizeEndpointPath = new PathString("/api/Account/ExternalLogin"),
AccessTokenExpireTimeSpan = TimeSpan.FromDays(14),
AllowInsecureHttp = true, // TODO Make false to deploy
};
app.UseOAuthAuthorizationServer(OAuthOptions);
}
}
到目前为止,我只使用过 /Token
端点,因为它至少会授予我不记名令牌。我在身份验证成功时收到的票有签发日期和到期日期、不记名令牌和我的用户名。
如何获得用户的声明(可能还有角色)?有什么我可以在这里做的事情,或者我在验证后通过 API 缓慢地请求它们,并将它们和 Auth Ticket 聚合在 WPF 客户端的 Principal
对象中?
我是否可以在 WPF 应用程序中包含一些身份组件以帮助从令牌中提取声明,以及关于我应该如何执行此操作的任何建议?
我认为让客户端解密令牌是相当危险的。如果他们能做到这一点,恶意行为者就可以修改令牌和其中的声明。如果您不检查声明的有效性(可能是因为它们是由第三方提供的),那么这可能会导致特权升级和您的应用程序受到损害。
如果客户端应用程序需要声明 - 也许是 UI 布局,那么您可以将它们单独提供给令牌。一种方法是通过 ActionFilterAttribute 将声明写入自定义 http header。如果声明在这里被篡改,它只会影响客户端,因为您将在处理任何请求之前检查令牌中的安全声明。
public AddClaimsAttribute : System.Web.Http.Filters.ActionFilterAttribute
{
var principal = actionExecutedContext.ActionContext.RequestContext.Principal as ClaimsPrincipal;
if (principal != null)
{
var claims = principal.Claims.Select(x => x.Type + ":" + x.Value).ToList();
actionExecutedContext.Response.Content.Headers.Add("Claims",
String.Join(",", claims));
}
}
然后您的客户端只需要检查这个 header 并解析它。
这是一个基本示例,您可以将其格式化为 JSON 或添加一系列自定义 headers "IsAdmin"、"IsEditingUser" 等
因为它是一个过滤器,所以您可以将其全局应用于每个请求、控制器上的每个操作或您需要的特定操作。
您可以通过在令牌响应中添加用户角色轻松实现此目的。为此,您必须在 ApplicationOAuthProvider.cs class 中更新方法 CreateProperties
public static AuthenticationProperties CreateProperties(User user)
{
//get only roles ids
//to do: retrieve user roles names
var roles = string.Join(",", user.Roles.Select(t => t.RoleId).ToArray());
//expose phone in response
var phone = user.PhoneNumber;
IDictionary<string, string> data = new Dictionary<string, string>
{
{ "userName", user.UserName },
{ "userId", user.Id },
{ "roles", roles},
{ "phone", phone}
};
return new AuthenticationProperties(data);
}
您可以在邮递员响应中看到 3 个新属性:userId、roles 和 phone。添加新属性时请注意空值。