2017-08-21 190 views
32

採用Core 1.1,隨後@ blowdart的意見,並實現了自定義的中間件:ASP.NET 2.0的核心中間件認證

https://stackoverflow.com/a/31465227/29821

它的工作是這樣的:

  1. 中間件跑。從請求標頭中提取一個令牌。
  2. 恪令牌,並且如果有效建立身份(ClaimsIdentity)含有其然後其經由HttpContext.User.AddIdentity添加了多個權利要求();
  3. 在使用services.AddAuthorization ConfigureServices我添加了一個政策,需要由中間件提供的要求。
  4. 在控制器/動作然後我會使用[授權(角色=「一些角色所添加的中間件」)]

這個有點與2.0工作,不同之處在於如果令牌是無效的(步驟2上面)並且聲明永遠不會被添加我得到「沒有指定authenticationScheme,並且沒有找到DefaultChallengeScheme。」

所以我現在要讀取,權威性在2.0改爲:

https://docs.microsoft.com/en-us/aspnet/core/migration/1x-to-2x/identity-2x

什麼,我做同樣的事情在ASP.NET 2.0的核心在正確的道路?我沒有看到一個例子,做真正的自定義驗證...

感謝

+0

試試這個鏈接,即使它說,2種方案,但它將給ü上的身份驗證HTTPS對決://wildermuth.com/2017/08/19/Two-AuthorizationSchemes-in-ASP-NET-Core-2 –

+0

您可以添加您的代碼,以便我們可以看看嗎?我知道我在core2.0的智威湯遜有問題 - 是在啓動時移動它的一個案例 – Webezine

回答

64

因此,試圖解決這個問題,經過漫長的一天,我終於想通了,微軟希望我們如何讓自定義驗證處理程序在覈心2.0新單曲的中間件的設置。

通過一些MSDN上的文檔尋找後,我發現了一個名爲AuthenticationHandler<TOption>類,它實現了IAuthenticationHandler接口。

從那裏,我發現了位於https://github.com/aspnet/Security

裏面的其中之一的現有認證方案的整個代碼庫,它顯示了微軟是如何實現JwtBearer認證方案。 (https://github.com/aspnet/Security/tree/dev/src/Microsoft.AspNetCore.Authentication.JwtBearer

我將大部分代碼複製到一個新文件夾中,並清除了所有與JwtBearer有關的事情。

JwtBearerHandler類(擴展AuthenticationHandler<>),有一個爲Task<AuthenticateResult> HandleAuthenticateAsync()

我在我們的舊中間件添加了對通過自定義令牌服務器設置要求的覆蓋,並且仍然遇到一些問題的權限,只是隨地吐痰如果令牌無效並且沒有設置索賠,則輸出200 OK而不是401 Unauthorized

我意識到我已經重寫了Task HandleChallengeAsync(AuthenticationProperties properties),無論什麼原因,它都是通過控制器中的[Authorize(Roles="")]來設置權限。

刪除此重寫後,代碼已經工作,並且在權限不匹配時已成功拋出401

從這個主要的外賣是,現在你不能使用自定義的中間件,你必須通過AuthenticationHandler<>實現它,你有DefaultAuthenticateSchemeDefaultChallengeScheme使用services.AddAuthentication(...)時設置。

下面的這是什麼都應該看起來像一個例子:

在Startup.cs/ConfigureServices()地址:

services.AddAuthentication(options => 
{ 
    // the scheme name has to match the value we're going to use in AuthenticationBuilder.AddScheme(...) 
    options.DefaultAuthenticateScheme = "Custom Scheme"; 
    options.DefaultChallengeScheme = "Custom Scheme"; 
}) 
.AddCustomAuth(o => { }); 

在Startup.cs /配置()地址:

app.UseAuthentication(); 

創建一個新文件CustomAuthExtensions.cs

public static class CustomAuthExtensions 
{ 
    public static AuthenticationBuilder AddCustomAuth(this AuthenticationBuilder builder, Action<CustomAuthOptions> configureOptions) 
    { 
     return builder.AddScheme<CustomAuthOptions, CustomAuthHandler>("Custom Scheme", "Custom Auth", configureOptions); 
    } 
} 

創建一個新的文件CustomAuthOptions.cs

public class CustomAuthOptions: AuthenticationSchemeOptions 
{ 
    public CustomAuthOptions() 
    { 

    } 
} 

創建一個新的文件CustomAuthHandler.cs

internal class CustomAuthHandler : AuthenticationHandler<CustomAuthOptions> 
{ 
    public CustomAuthHandler(IOptionsMonitor<CustomAuthOptions> options, ILoggerFactory logger, UrlEncoder encoder, ISystemClock clock) : base(options, logger, encoder, clock) 
    { 
     // store custom services here... 
    } 
    protected override async Task<AuthenticateResult> HandleAuthenticateAsync() 
    { 
     // build the claims and put them in "Context"; you need to import the Microsoft.AspNetCore.Authentication package 
     return AuthenticateResult.NoResult(); 
    } 
} 
+1

偉大的文章,但我有一些問題編譯你的代碼。 CustomAuthOptions和AuthenticateResult類型缺失。你可以發佈這些? – alexb

+0

CustomAuthOptions是一個繼承自AuthenticationSchemeOptions的簡單空類。 AuthenticateResult在Microsoft.AspNetCore.Authentication中定義(您需要導入該包)。 – pbz

+0

@alexb我編輯了原始答案以解決您的觀點。 – pbz

0

個人信息中有以核2.0相當大的變化,從核心的1.x爲您引用的文章指出。主要變化是擺脫中間件方法,並使用依賴注入來配置定製服務。這爲定製更復雜實現的Identity提供了更多的靈活性。所以你想擺脫上面提到的中間件方法並轉向服務。按照參考文章中的遷移步驟實現此目標。通過app.UseAuthentication更換app.UseIdentity啓動。 UseIdentity折舊並不會在將來的版本中得到支持。有關如何插入一個自定義聲明變換和在權利要求view this blog post執行授權一個完整的示例。

+4

有沒有關於如何在WebAPI應用中使用它的例子? – alexb