重定向到 URL 而不是未经身份验证的 401

Redirect to URL instead of 401 for unauthenticated

我正在使用 ASP.Net 5 MVC 6 和 JWT 令牌,这些令牌是在用户访问另一个站点时创建的,该站点是该站点的子域。我的目标是将令牌连同请求一起传递到该子域。如果用户碰巧在 header 中没有正确的令牌就尝试访问此子域 url 那么我想将他们重定向到主站点登录页面。

在对最新的 RC-1 版本和使用带有 SecureKey 而不是证书的 JWT 令牌感到非常沮丧之后。我终于通过使用 RC-2 每晚构建版本让我的代码工作了。现在我的问题是,在未经身份验证的用户的情况下,我希望能够重定向到外部 url。这是我的验证码示例:

        var key = "mysupersecretkey=";
        var encodedkey2 = Convert.FromBase64String(key);
        app.UseJwtBearerAuthentication(options =>
        {
            options.AutomaticAuthenticate = true;
            options.AutomaticChallenge = true;
            options.TokenValidationParameters.IssuerSigningKey = new SymmetricSecurityKey(encodedkey2);
            options.TokenValidationParameters.ValidIssuer = "https://tv.alsdkfalsdkf.com/xxx/yyy";
            options.TokenValidationParameters.ValidateIssuer = true;
            options.TokenValidationParameters.ValidAudience = "https://www.sdgfllfsdkgh.com/";
            options.TokenValidationParameters.ValidateAudience = true;
            options.Configuration = new Microsoft.IdentityModel.Protocols.OpenIdConnect.OpenIdConnectConfiguration()
            {
                Issuer = "https://tv.sdfkaysdf.com/xxx/yyy"
            };
        });

现在我看到其他使用 OpedId 的示例,它们非常简单,有一个名为 RedirectUrl

的参数
 app.UseOpenIdConnectAuthentication(options => {
    ...
    options.RedirectUri = "https://localhost:44300";
    ...
 });

知道如何在使用 JwtBearerAuthentication 时设置 RedirectUrl 吗???

没有这样的 属性 原因很简单:JWT 承载中间件(如 Katana 中更通用的 OAuth2 中间件)专为 API 身份验证而不是交互式身份验证而设计。在这种情况下尝试触发重定向对于无头 HTTP 客户端来说意义不大。

也就是说,这并不意味着您在某些时候 完全 无法重定向未经身份验证的用户。处理该问题的最佳方法是在客户端捕获 JWT 中间件返回的 401 响应,并将用户重定向到适当的登录页面。例如在 JS 应用程序中,this is usually done using an HTTP interceptor.

如果您真的相信breaking the OAuth2 bearer specification是正确的做法,您可以使用OnChallenge通知来做到这一点:

app.UseJwtBearerAuthentication(options => {
    options.Events = new JwtBearerEvents {
        OnChallenge = context => {
            context.Response.Redirect("http://localhost:54540/login");
            context.HandleResponse();

            return Task.FromResult(0);
        }
    };
});