如何在没有 IdentityServer 或 OAuth 的情况下配置 JWT STS

Posted

技术标签:

【中文标题】如何在没有 IdentityServer 或 OAuth 的情况下配置 JWT STS【英文标题】:How to configure a JWT STS without IdentityServer or OAuth 【发布时间】:2019-09-04 20:39:12 【问题描述】:

我想在不使用 IdentityServer 或 OAuth 的情况下构建 JWT 安全令牌服务(.net core 2+)来为许多 API(.net core 2+)提供身份验证和授权,因为我希望 没有重定向.

“JWT Authenticator”工作正常并且有路由

POST 帐户:注册新用户 POST Auth/Login:如果凭据有效,则返回 jwt 令牌 POST 令牌:刷新令牌 POST Token/Revoke:撤销令牌

但是,我很难提供第 4 步和第 5 步。我在 API1/Startup.cs -> ConfigureServices 尝试了许多选项,但在调用 GET API1/Resource 时除了 404 之外没有任何结果。 ConfigureServices 方法还是这样的:

 public void ConfigureServices(IServiceCollection services)
    
        services.AddAuthentication(options =>
        
            options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
            options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
            options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
        )
       .AddJwtBearer(options =>
       
           options.Authority = "http://localhost:6000"; // JWT Authenticator address
           options.RequireHttpsMetadata = false;
           options.SaveToken = true;
           options.TokenValidationParameters = new TokenValidationParameters
               
               ValidIssuer = _configuration.GetValue<string>("JwtIssuer"),
               ValidAudience = _configuration.GetValue<string>("JwtAudience"),
               IssuerSigningKey = new SymmetricSecurityKey(
                   Encoding.UTF8.GetBytes(_configuration.GetValue<string>("JwtSecretKey"))),
               ClockSkew = TimeSpan.Zero
           ;
       );

        services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
    

是否可以使用 AddJwtBearer 之类的方法配置步骤 4 和 5?如果没有,我该怎么办?使用 API1 的授权过滤器拦截请求并向 JWT Authenticator 发出请求以验证令牌/获取声明/等?

【问题讨论】:

看起来您刚刚重新发明了资源所有者密码流程。无论如何,JWT 通常不会通过反向通道调用重新验证,因为它们使用非对称加密来证明颁发者和有效性。 “因为我不想重定向” – 重定向只是 OAuth 中少数特定身份验证流程的一部分,主要是为了保护用户,因为应用程序不可信用密码。这并不意味着没有允许此如果您可以信任该应用程序的流程。 – 实现自己的身份验证协议通常是一个非常糟糕的主意,因为它非常困难。所以我建议你改用现有的协议和经过良好测试的库来实现这些。 【参考方案1】:

一些想法...

您的 4 和 5 条路径;通常你不会询问令牌的提供者是否有效。您所做的是验证这一点,最有可能使用签名,可以(可选)从提供程序下载哪些参数。

注意细微的差别:提供者本身不会检查它。

下一步: ClockSkew = TimeSpan.Zero,这很少。我至少会给它一些松懈。

至少;有404 表示找不到资源。这不是401403。此提示授权成功但未找到请求的资源。


签名验证的典型实现:

注意这并不能解决您的 404。

options.TokenValidationParameters = new TokenValidationParameters

    IssuerSigningKeyResolver = (s, securityToken, identifier, parameters) =>
    
        // get from provider 
        // todo: cache this
        var json = new WebClient().DownloadString(
             issuer + "/.well-known/jwks.json"); //typical endpoint

        // serialize the result
        var keys = JsonConvert.DeserializeObject<JsonWebKeySet>(json).Keys;
        // cast the result to be the type expected by IssuerSigningKeyResolver
        return (IEnumerable<SecurityKey>) keys;
    
//...

【讨论】:

以上是关于如何在没有 IdentityServer 或 OAuth 的情况下配置 JWT STS的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 IdentityServer 4 实现 Windows 身份验证

如何从 identityServer4 的现有数据库中获取用户

如何使用IdentityServer3进行登录吗

IdentityServer4如何创建身份令牌?

如何加固 IdentityServer4 以用于生产?

IdentityServer3 + AzureAD 和 RedirectUri 混淆