如何在Web API身份验证服务中获取AuthTicket中包含的声明?

时间:2022-11-29 07:23:47

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。

如何在Web API身份验证服务中获取AuthTicket中包含的声明?

#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。

如何在Web API身份验证服务中获取AuthTicket中包含的声明?