Resource Server中的OwinMiddleware实现禁止令牌验证

时间:2017-08-03 01:28:03

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

我已经设置了我的资源服务器(Web Api 2)来验证传入请求的JWT令牌。 JWT令牌由Aut​​h0发布,我的客户端将其传递给我的web api。如果发行人,受众或到期日无效,这一切都可以正常工作并提出401响应。当我添加从OwinMiddleware派生的自定义中间件时,它会抑制令牌验证逻辑,我会收到200个无效请求的响应。

public class Startup
{
    public void Configuration(IAppBuilder app)
    {
         var issuer = "my issuer";
         var audience= "my audience";
         var clientId= "my client id";
         app.UseActiveDirectoryFederationServicesBearerAuthentication(
            new ActiveDirectoryFederationServicesBearerAuthenticationOptions
            {
                TokenValidationParameters = new TokenValidationParameters
                {
                    ValidAudience = audience,
                    ValidIssuer = issuer,
                    IssuerSigningKeyResolver = (token, securityToken, identifier, parameters) => parameters.IssuerSigningTokens.FirstOrDefault()?.SecurityKeys?.FirstOrDefault()
                },
                // Setting the MetadataEndpoint so the middleware can download the RS256 certificate
                MetadataEndpoint = $"{issuer.TrimEnd('/')}/wsfed/{clientId}/FederationMetadata/2007-06/FederationMetadata.xml"
            });



        HttpConfiguration config = new HttpConfiguration();

        app.Use<HttpUsernameInjector>();

        // Web API routes
        config.MapHttpAttributeRoutes();
        app.UseWebApi(config);
    }
}

和我的自定义OwinMiddleWare:

public class HttpUsernameInjector : OwinMiddleware
{
    public HttpUsernameInjector(OwinMiddleware next)
        : base(next)
    {
    }

    public override async Task Invoke(IOwinContext context)
    {
        const string usernameClaimKey = "my username claim key";

        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 个答案:

答案 0 :(得分:0)

OWINMiddleware没有任何问题,但分配context.Request.User会导致问题。此处创建的GenericIdentity的Readonly IsAuthenticated等于true,无法设置为false。分配context.Request.User = genericPrincipal;时,IsAuthenticated覆盖context.Request.User内的IsAuthenticated genericPrincipal IsAuthenticated。需要在Invoke方法的开头检查身份验证结果,如果用户未经过身份验证,则跳过逻辑。因此,它不会更改context.Request.User中的public override async Task Invoke(IOwinContext context) { if (context.Authentication.User.Identity.IsAuthenticated) { //my username injection logic } await Next.Invoke(context); }

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = guestTableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) 

    let button : UIButton = UIButton(type:UIButtonType.custom) as UIButton

    button.frame = CGRect(origin: CGPoint(x: 200,y :60), size: CGSize(width: 100, height: 24))
    let cellHeight: CGFloat = 44.0
    button.center = CGPoint(x: view.bounds.width / (4/3), y: cellHeight / 2.0)


    button.setTitleColor(.blue, for: .normal)
    button.addTarget(self, action: #selector(buttonClicked), for: UIControlEvents.touchUpInside)
    button.setTitle("Add", for: UIControlState.normal)

    cell.addSubview(button)


    return cell
}

func buttonClicked(sender : UIButton!) {
    print("Added!")


}