【问题标题】:Configuring Web Api 2 as Resource Server using OWIN使用 OWIN 将 Web Api 2 配置为资源服务器
【发布时间】:2017-12-25 18:35:21
【问题描述】:

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

状态:

 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);
    }
}

和 Auth0Config 类:

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;
                    }
                }
            });
    }
}

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

我的行动:

[Authorize]
public IHttpActionResult Get(string id)
{
    var result = _bookingService.GetBooking(id);
    if (result == null) return NotFound();
    return Ok(result);
}
  1. 我是否遗漏了一些东西来使它正确?
  2. 这是验证令牌过期的好方法吗?
  3. 是否可以仅使用 OWIN 来验证从 Web api 应用程序发出的请求 Bearer 令牌?

【问题讨论】:

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


    【解决方案1】:
    1. 原来 OwinMiddleware 类的 Invoke 方法已在我的应用程序中被覆盖,以从令牌中查找用户名并将其注入 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);
        }
      }
      

    通过删除此类,OWIN 令牌验证工作正常!

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

    更新

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

    【讨论】:

      猜你喜欢
      • 2016-03-12
      • 2015-04-16
      • 2017-04-03
      • 1970-01-01
      • 2017-02-13
      • 2017-12-23
      • 1970-01-01
      • 1970-01-01
      • 2015-02-27
      相关资源
      最近更新 更多