I have a Web API with an auth service, for a WPF client, set up like this:
我有一个带有auth服务的Web API,对于WPF客户端,设置如下:
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
config.SuppressDefaultHostAuthentication();
config.Filters.Add(new HostAuthenticationFilter(OAuthDefaults.AuthenticationType));
...
}
}
and
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);
}
}
I only ever use the /Token
endpoint so far, because it at least grants me the bearer token. The ticket I receive on a successful authentication has issue and expiry dates, a bearer token, and my username.
到目前为止我只使用/ Token端点,因为它至少授予我持票令牌。我在成功验证时收到的票证有问题和到期日期,持有人令牌和我的用户名。
How do I get the user's claims (and maybe roles)? Is there something I can do here, or I do I plod along and request them via the API, after auth, and aggregate them and the Auth Ticket in something like a Principal
object for the WPF client?
如何获得用户的声明(可能还有角色)?我可以在这里做些什么,或者我是否可以在auth之后通过API请求它们,并将它们和Auth Ticket聚合在一起,就像WPF客户端的Principal对象一样?
Could I perhaps include some Identity components in the WPF app to help with extracting the claims from the token, and any suggestions on how I should do this?
我是否可以在WPF应用程序中包含一些Identity组件,以帮助从令牌中提取声明,以及有关如何执行此操作的任何建议?
2 个解决方案
#1
3
I think it is quite dangerous to allow the client to decrypt the token. If they can do that, a malicious actor can modify the token and the claims inside. If you don't check the validity of the claims (perhaps because they are provided by a third party) then that could lead to privilege escalation and compromise of your application.
我认为允许客户端解密令牌是非常危险的。如果他们可以这样做,恶意行为者可以修改令牌和内部的声明。如果您不检查声明的有效性(可能是因为它们是由第三方提供的),那么这可能会导致权限升级并损害您的应用程序。
If the client application requires the claims - perhaps for UI layout, then you can supply them separately to the token. One way to do this would be via an ActionFilterAttribute to write the claims to a custom http header. If the claims are tampered with here, it only affects the client, as you will check the secure claims inside the token before processing any request.
如果客户端应用程序需要声明 - 可能是UI布局,那么您可以将它们单独提供给令牌。一种方法是通过ActionFilterAttribute将声明写入自定义http标头。如果声明在此处被篡改,则它仅影响客户端,因为您将在处理任何请求之前检查令牌内的安全声明。
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));
}
}
Your client then just needs to check for this header and parse it.
然后您的客户端只需检查此标头并解析它。
This is a basic example, you could format it as JSON or add a series of custom headers "IsAdmin", "IsEditingUser" etc.
这是一个基本示例,您可以将其格式化为JSON或添加一系列自定义标题“IsAdmin”,“IsEditingUser”等。
Because it is a filter, you could apply this globally to every request, to every action on a controller or to a specific action as you need it.
因为它是一个过滤器,所以您可以将其全局应用于每个请求,控制器上的每个操作或您需要的特定操作。
#2
2
You can easily achieve this by adding user roles in token response. In order to do this you have to update in ApplicationOAuthProvider.cs class the method CreateProperties
您可以通过在令牌响应中添加用户角色来轻松实现此目的。为此,您必须在ApplicationOAuthProvider.cs类中更新方法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);
}
You can see in postman response 3 new properties: userId,roles and phone. Be carrefull for null values when you will add new properties.
您可以在postman响应中看到3个新属性:userId,roles和phone。在添加新属性时,请为null值添加carrefull。
#1
3
I think it is quite dangerous to allow the client to decrypt the token. If they can do that, a malicious actor can modify the token and the claims inside. If you don't check the validity of the claims (perhaps because they are provided by a third party) then that could lead to privilege escalation and compromise of your application.
我认为允许客户端解密令牌是非常危险的。如果他们可以这样做,恶意行为者可以修改令牌和内部的声明。如果您不检查声明的有效性(可能是因为它们是由第三方提供的),那么这可能会导致权限升级并损害您的应用程序。
If the client application requires the claims - perhaps for UI layout, then you can supply them separately to the token. One way to do this would be via an ActionFilterAttribute to write the claims to a custom http header. If the claims are tampered with here, it only affects the client, as you will check the secure claims inside the token before processing any request.
如果客户端应用程序需要声明 - 可能是UI布局,那么您可以将它们单独提供给令牌。一种方法是通过ActionFilterAttribute将声明写入自定义http标头。如果声明在此处被篡改,则它仅影响客户端,因为您将在处理任何请求之前检查令牌内的安全声明。
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));
}
}
Your client then just needs to check for this header and parse it.
然后您的客户端只需检查此标头并解析它。
This is a basic example, you could format it as JSON or add a series of custom headers "IsAdmin", "IsEditingUser" etc.
这是一个基本示例,您可以将其格式化为JSON或添加一系列自定义标题“IsAdmin”,“IsEditingUser”等。
Because it is a filter, you could apply this globally to every request, to every action on a controller or to a specific action as you need it.
因为它是一个过滤器,所以您可以将其全局应用于每个请求,控制器上的每个操作或您需要的特定操作。
#2
2
You can easily achieve this by adding user roles in token response. In order to do this you have to update in ApplicationOAuthProvider.cs class the method CreateProperties
您可以通过在令牌响应中添加用户角色来轻松实现此目的。为此,您必须在ApplicationOAuthProvider.cs类中更新方法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);
}
You can see in postman response 3 new properties: userId,roles and phone. Be carrefull for null values when you will add new properties.
您可以在postman响应中看到3个新属性:userId,roles和phone。在添加新属性时,请为null值添加carrefull。