2017-05-09 37 views
2

我開發的認證服務器提供的令牌被用來消耗使用IdentityServer4我們的API。 我正在使用MongoDB作爲數據庫,我讓用戶可以獲取令牌,並且更安全我正在使用自定義證書來加密令牌。 這是我Startup.cs我AuthenticationServer的樣子:身份服務器4 - 禁用發現端點

public void ConfigureServices(IServiceCollection services) 
{ 
    services.Configure<AppSettings>(Configuration.GetSection("AppSettings")); 

    var cert = new X509Certificate2(Path.Combine(_environment.ContentRootPath, "cert", "whatever.pfx"), "whatever"); 

    services.AddIdentityServer().AddSigningCredential(cert) 
      .AddInMemoryApiResources(Config.Config.GetApiResources()); 

    services.AddTransient<IUserRepository, UserRepository>(); 

    services.AddTransient<IClientStore, ClientStore>(); 
    services.AddTransient<IProfileService, UserProfileService>(); 
    services.AddTransient<IResourceOwnerPasswordValidator, UserResourceOwnerPasswordValidator>(); 
    services.AddTransient<IPasswordHasher<User.Model.User>, PasswordHasher<User.Model.User>>(); 

} 

正如你可以看到我有那些做客戶端身份驗證和密碼驗證界面的自定義實現。這工作正常。

然後我保護另一個應用程序與生成的令牌,我也有定義的,它必須使用IdentityServerAuthetication(本地主機:5020是我的AuthenticationServer運行)

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) 
    { 
     app.UseCors("CorsPolicy"); 

     loggerFactory.AddConsole(Configuration.GetSection("Logging")); 
     loggerFactory.AddDebug(); 

     app.UseIdentityServerAuthentication(new IdentityServerAuthenticationOptions 
     { 
      Authority = "http://localhost:5020", 
      RequireHttpsMetadata = false, 
      ApiName = "MyAPI", 
      RoleClaimType = JwtClaimTypes.Role 
     }); 

     app.UseMvc(); 
    } 

一切工作正常,但如果我關閉AuthenticationServer然後我從我保護API此錯誤:

System.InvalidOperationException:IDX10803:無法從獲得的配置:'http://localhost:5020/.well-known/openid-configuration'。 at Microsoft.IdentityModel.Protocols.ConfigurationManager`1.d__24.MoveNext() ---從以前的位置拋出異常的堆棧跟蹤結束--- 在System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(任務任務) 在System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任務的任務) 在Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerHandler.d__1.MoveNext() 失敗:Microsoft.AspNetCore.Server.Kestrel [13]

因此,API看起來是發現端點,看看端點在哪裏解密令牌(我想這將是userinfo_endpoint)。

我的觀點是:

  • 看來,發現端點用來獲取如何使用認證服務器信息(對我來說是有道理的,開放的API),但是對我們來說,我們不發展和開放的API,所以我們的客戶將只是我們已經達成的協議,我們會提前告訴他們端點,我們很可能會限制IP地址。
  • 有什麼辦法停用發現端點和設置的API證書正確地解密令牌。

也許我錯過了整個圖片,我說的是愚蠢的事情,但我很樂意瞭解背後的概念。 在此先感謝

回答

0

IdentityServer需要您的X509證書的公鑰來驗證access_token。它使用發現端點來獲取該公鑰,並且不時刷新保存的公鑰(因爲公鑰可能會更改)。

如果IdentityServer是無法訪問的,您的API不能保證access_token是有效的。您可以增加對access_token驗證請求結果的緩存。

我並不完全確定IdentityServer4.AccessTokenValidation,但是IdentityServer3.AccessTokenValidation只能將ValidationMode設置爲Local,所以它只是下載一次公鑰。

0

有可能使發現端點關閉/不可用,並且仍然驗證令牌。

您需要實現IConfigurationManager並將其傳遞給IdentityServerAuthenticationOptions中的JwtBearerOptions對象。

下面是一些示例代碼:

public class OidcConfigurationManager : IConfigurationManager<OpenIdConnectConfiguration> 
{ 
    public OidcConfigurationManager() 
    { 
     SetConfiguration(); 
    } 
    private OpenIdConnectConfiguration _config; 
    public Task<OpenIdConnectConfiguration> GetConfigurationAsync(CancellationToken cancel) 
    { 
     return Task.FromResult<OpenIdConnectConfiguration>(_config); 
    } 
    public void RequestRefresh() 
    { 
    } 

    private void SetConfiguration() 
    { 
     // Build config from JSON 
     var configJson = 
      @"{""issuer"":""http://localhost/id"",""jwks_uri"":""http://localhost/id/.well-known/openid-configuration/jwks"",""authorization_endpoint"":""http://localhost/id/connect/authorize"",""token_endpoint"":""http://localhost/id/connect/token"",""userinfo_endpoint"":""http://localhost/id/connect/userinfo"",""end_session_endpoint"":""http://localhost/id/connect/endsession"",""check_session_iframe"":""http://localhost/id/connect/checksession"",""revocation_endpoint"":""http://localhost/id/connect/revocation"",""introspection_endpoint"":""http://localhost/id/connect/introspect"",""frontchannel_logout_supported"":true,""frontchannel_logout_session_supported"":true,""scopes_supported"":[""openid"",""profile"",""api1"",""offline_access""],""claims_supported"":[""sub"",""name"",""family_name"",""given_name"",""middle_name"",""nickname"",""preferred_username"",""profile"",""picture"",""website"",""gender"",""birthdate"",""zoneinfo"",""locale"",""updated_at""],""grant_types_supported"":[""authorization_code"",""client_credentials"",""refresh_token"",""implicit"",""password""],""response_types_supported"":[""code"",""token"",""id_token"",""id_token token"",""code id_token"",""code token"",""code id_token token""],""response_modes_supported"":[""form_post"",""query"",""fragment""],""token_endpoint_auth_methods_supported"":[""client_secret_basic"",""client_secret_post""],""subject_types_supported"":[""public""],""id_token_signing_alg_values_supported"":[""RS256""],""code_challenge_methods_supported"":[""plain"",""S256""]}"; 
     _config = new OpenIdConnectConfiguration(configJson); 

     // Add signing keys if not present in json above 
     _config.SigningKeys.Add(new X509SecurityKey(cert)); 
    } 
} 

現在通過這個配置對象的你IdentityServerAuthenticationOptions內一些JwtBearerOptions(有點討厭,但它是我知道的唯一途徑)

var identityServerOptions = new IdentityServerAuthenticationOptions 
{ 
    Authority = "http://localhost:5020", 
    RequireHttpsMetadata = false, 
    ApiName = "MyAPI", 
    RoleClaimType = JwtClaimTypes.Role, 

}; 
var jwtBearerOptions = new JwtBearerOptions() {ConfigurationManager = new OidcConfigurationManager()}; 
var combinedOptions = CombinedAuthenticationOptions.FromIdentityServerAuthenticationOptions(identityServerOptions); 
combinedOptions.JwtBearerOptions = jwtBearerOptions; 
app.UseIdentityServerAuthentication(combinedOptions); 

現在即使OIDC發現端點關閉,您的API也能夠接收令牌並驗證簽名。

0

API驗證中間件在啓動時下載發現文檔的副本 - 然後(至少默認情況下)每24小時下載一次。

如果簽名驗證失敗(以適應計劃外的密鑰翻轉),它可能會重新觸發下載。

您可以靜態定義所有配置值 - 但您失去了動態配置更新的所有好處。

如果您的發現端點不可用,那麼整個令牌服務可能不起作用,這可能是一個更大的問題。

+0

這是否意味着擁有可用的發現端點不會造成安全風險? ..我來自WCF,我不得不禁用端點的元數據。 – Learner