使用OWIN将Web Api 2配置为资源服务器

时间:2017-07-20 07:37:25

标签: authentication asp.net-web-api owin access-token auth0

尝试将我的Web Api配置为资源服务器。我的客户端登录到Auth0并获取Bearer令牌,因此Authorization Server是Auth0而不是我的Api。然后他们将请求和Bearer令牌一起发送给我的Api。在我的ASP.Net Web Api中,我在Startup类中实现了以下OWIN配置,以按照指示here验证Auth0发出的请求JWT Bearer令牌。

Statup:

map $http_cookie $auth_header {
    default "";
    "~*yourCookieName=(?<variable>[^;]+)" "the value you wanna set $variable";
  }

和Auth0Config类:

 public class Startup
{
    public void Configuration(IAppBuilder app)
    {

        var auth0Options = new Auth0Options()
        {
            Issuer = $"https://{ConfigurationManager.AppSettings["Auth0ApiInternalDomain"]}/",
            Audience = ConfigurationManager.AppSettings["Auth0ApiInternalAudience"],
            ClientId = ConfigurationManager.AppSettings["Auth0ApiInternalClientID"]
        };

        Auth0Config.Configure(app, auth0Options);

        // Configure Web API
        WebApiConfig.Configure(app);
    }
}

我将app.config中的Audience,Issuer和CliedntId传递给此方法。我的目的是弄清楚从客户端到我的Api的Bearer令牌是否有效(这是我需要验证到期日期的第一步)。当我调试传入请求的代码时, LifetimeValidator 工作正常,并为过期的令牌返回false。我用[授权]修饰了我的动作并且预计会得到401错误,但实际响应是200,它似乎忽略了 LifetimeValidator 实现。

我的行动:

public class Auth0Config
{
    public static void Configure(IAppBuilder app, Auth0Options options)
    {
        if (options == null)
            throw new ArgumentNullException(nameof(options));

        var keyResolver = new OpenIdConnectSigningKeyResolver(options.Issuer);

        app.UseJwtBearerAuthentication(
            new JwtBearerAuthenticationOptions
            {
                AuthenticationMode = AuthenticationMode.Active,
                TokenValidationParameters = new TokenValidationParameters()
                {
                    ValidAudience = options.Audience,
                    ValidIssuer = options.Issuer,
                    IssuerSigningKeyResolver = (token, securityToken, identifier, parameters) => keyResolver.GetSigningKey(identifier),
                    ValidateLifetime = true,
                    ValidateIssuer = true,
                    ValidateAudience = true,
                    LifetimeValidator = (DateTime? notBefore, DateTime? expires, SecurityToken securityToken, TokenValidationParameters validationParameters) =>
                    {
                        if (expires.Value < DateTime.UtcNow)
                        {
                            return false;
                        }
                        return true;
                    }
                }
            });
    }
}
  1. 我错过了什么来做对吗?
  2. 这是验证令牌过期的好方法吗?
  3. 是否可以仅使用OWIN验证从web api应用程序发出的请求承载令牌?

1 个答案:

答案 0 :(得分:1)

  1. 事实证明,OwinMiddleware类的Invoke方法已在我的应用程序中被覆盖,以便从令牌中找到Username并将其注入Request.User。不确定为什么但不知何故它忽略了OWIN令牌验证功能,并且没有检查受众,发行者或过期时间。

    public static void Configure(IAppBuilder app)
    {
        HttpConfiguration config = new HttpConfiguration();
        app.Use<HttpUsernameInjector>();
        app.UseWebApi(config);
    }
    
    public class HttpUsernameInjector : OwinMiddleware
    {
      public HttpUsernameInjector(OwinMiddleware next)
        : base(next){}
    
      public override async Task Invoke(IOwinContext context)
      {
        const string usernameClaimKey = "myUserNameClaimKey";
    
        var bearerString = context.Request.Headers["Authorization"];
        if (bearerString != null && bearerString.StartsWith("Bearer ", StringComparison.InvariantCultureIgnoreCase))
        {
            var tokenString = bearerString.Substring(7);
    
            var token = new JwtSecurityToken(tokenString);
            var claims = token.Claims.ToList();
            var username = claims.FirstOrDefault(x => x.Type == usernameClaimKey);
    
            if (username == null) throw new Exception("Token should have username");
    
            // Add to HttpContext
            var genericPrincipal = new GenericPrincipal(new GenericIdentity(username.Value), new string[] { });
    
            IPrincipal principal = genericPrincipal;
    
            context.Request.User = principal;
        }
    
        await Next.Invoke(context);
      }
    }
    
  2. 通过删除此类,OWIN令牌验证工作正常!

    1. 根据我的研究,Web Api中最好的令牌验证方法是 OWIN 以及 IAuthenticationFilter
    2. 可以将资源服务器和授权服务器解耦。更多信息可以在here
    3. 找到

      <强> 更新

      找到解决方案here以阻止OwinMiddleware抑制我的令牌验证逻辑