มิดเดิลแวร์การพิสูจน์ตัวตน ASP.NET Core 2.0


91

ด้วย Core 1.1 ตามคำแนะนำของ @ blowdart และใช้มิดเดิลแวร์ที่กำหนดเอง:

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

มันทำงานเช่นนี้:

  1. มิดเดิลแวร์วิ่ง เลือกโทเค็นจากส่วนหัวของคำขอ
  2. ตรวจสอบโทเค็นและหากถูกต้องสร้างข้อมูลประจำตัว (ClaimsIdentity) ที่มีการอ้างสิทธิ์หลายรายการซึ่งเพิ่มผ่าน HttpContext.User.AddIdentity ();
  3. ใน ConfigureServices โดยใช้บริการ AddAuthorization ฉันได้เพิ่มนโยบายเพื่อต้องการการอ้างสิทธิ์ที่มาจากมิดเดิลแวร์
  4. ในตัวควบคุม / การดำเนินการฉันจะใช้ [Authorize (Roles = "some role that the middleware added")]

สิ่งนี้ใช้ได้กับ 2.0 บ้างยกเว้นว่าหากโทเค็นไม่ถูกต้อง (ขั้นตอนที่ 2 ด้านบน) และไม่มีการเพิ่มการอ้างสิทธิ์ฉันได้รับ "ไม่ได้ระบุการตรวจสอบความถูกต้องและไม่พบ DefaultChallengeScheme"

ตอนนี้ฉันกำลังอ่านการรับรองความถูกต้องที่เปลี่ยนแปลงใน 2.0:

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

อะไรคือเส้นทางที่ถูกต้องสำหรับฉันในการทำสิ่งเดียวกันใน ASP.NET Core 2.0 ฉันไม่เห็นตัวอย่างในการตรวจสอบสิทธิ์แบบกำหนดเองอย่างแท้จริง


ลองใช้ลิงค์นี้แม้ว่ามันจะบอกว่า 2 schemes แต่มันจะช่วยให้คุณทราบเกี่ยวกับ Authentication wildermuth.com/2017/08/19/…
Mithun Pattankar

คุณช่วยเพิ่มรหัสของคุณเพื่อให้เราดูได้ไหม ฉันรู้ว่าฉันมีปัญหากับ JWT ใน core2.0 - เป็นกรณีของการย้ายไปรอบ ๆ ในการเริ่มต้น
Webezine

คำตอบ:


198

ดังนั้นหลังจากพยายามแก้ปัญหานี้มาทั้งวันในที่สุดฉันก็พบว่า Microsoft ต้องการให้เราสร้างตัวจัดการการรับรองความถูกต้องแบบกำหนดเองสำหรับการตั้งค่ามิดเดิลแวร์เดี่ยวใหม่ใน core 2.0

หลังจากดูเอกสารบางส่วนใน MSDN ฉันพบคลาสที่เรียกAuthenticationHandler<TOption>ว่าใช้IAuthenticationHandlerอินเทอร์เฟซ

จากนั้นฉันพบโค้ดเบสทั้งหมดที่มีรูปแบบการตรวจสอบสิทธิ์ที่มีอยู่ที่https://github.com/aspnet/Security

ภายในหนึ่งในนั้นแสดงให้เห็นว่า Microsoft ใช้รูปแบบการรับรองความถูกต้อง JwtBearer อย่างไร ( https://github.com/aspnet/Security/tree/master/src/Microsoft.AspNetCore.Authentication.JwtBearer )

JwtBearerผมคัดลอกที่สุดของรหัสว่ากว่าลงในโฟลเดอร์ใหม่และออกมาเคลียร์ทุกสิ่งที่ต้องทำอย่างไรกับ

ในJwtBearerHandlerชั้นเรียน (ซึ่งขยายออกไปAuthenticationHandler<>) มีการแทนที่สำหรับTask<AuthenticateResult> HandleAuthenticateAsync()

ฉันได้เพิ่มมิดเดิลแวร์เก่าของเราสำหรับการตั้งค่าการอ้างสิทธิ์ผ่านเซิร์ฟเวอร์โทเค็นที่กำหนดเองและยังคงพบปัญหาบางอย่างเกี่ยวกับสิทธิ์เพียงแค่พ่น a 200 OKแทน401 Unauthorizedเมื่อโทเค็นไม่ถูกต้องและไม่มีการตั้งค่าการอ้างสิทธิ์

ฉันตระหนักว่าฉันได้ลบล้างTask HandleChallengeAsync(AuthenticationProperties properties)ซึ่งใช้ในการตั้งค่าการอนุญาตผ่าน[Authorize(Roles="")]ตัวควบคุมด้วยเหตุผลใดก็ตาม

หลังจากลบการลบล้างนี้โค้ดก็ใช้งานได้และประสบความสำเร็จในการโยน401เมื่อสิทธิ์ไม่ตรงกัน

Takeaway ที่หลักจากนี้คือว่าตอนนี้คุณไม่สามารถใช้ตัวกลางที่กำหนดเองคุณต้องใช้มันผ่านAuthenticationHandler<>และคุณจะต้องตั้งค่าDefaultAuthenticateSchemeและเมื่อใช้DefaultChallengeSchemeservices.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 / Configure () เพิ่ม:

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

8
คุณยินดีที่จะแบ่งปันข้อสรุปของคุณในโค้ดบน repo Github หรือไม่?
CSharper

2
คุณช่วยอธิบายDefaultAuthenticateSchemeและDefaultChallengeScheme? ฉันไม่เข้าใจว่าทำไมถึงใช้ทั้งคู่? และอะไรคือความแตกต่างระหว่างพวกเขา
Mohammed Noureldin

11
+1 สำหรับ "จากนั้นฉันพบโค้ดเบสทั้งหมดที่มีรูปแบบการตรวจสอบสิทธิ์ที่มีอยู่ที่github.com/aspnet/Security " เพียงแค่ดูว่าทีม ASP.NET ทำอย่างไรเมื่อคุณทำตามพร้อมกับคำตอบนี้ (ยอดเยี่ยมจริงๆ) พวกเราทุกคนเคยคิดไหมว่าวันหนึ่งเราจะถามคำถามเกี่ยวกับรหัส MS และแนวทางปฏิบัติและคำตอบคือ
Marc L.

3
สำหรับคนอื่น ๆ ที่เข้ามาในภายหลังคุณAuthExtensionจำเป็นต้องอยู่ในMicrosoft.Extensions.DependencyInjectionเนมสเปซ ดูตัวอย่างนี้: github.com/aspnet/Security/blob/rel/2.0.0/src/…
Garry Polley

4

มีการเปลี่ยนแปลงอย่างมากใน Identity จาก Core 1.x เป็น Core 2.0 ตามบทความที่คุณอ้างอิงชี้ให้เห็น การเปลี่ยนแปลงที่สำคัญคือการหลีกเลี่ยงวิธีการของมิดเดิลแวร์และการใช้การฉีดการพึ่งพาเพื่อกำหนดค่าบริการที่กำหนดเอง สิ่งนี้ให้ความยืดหยุ่นมากขึ้นในการปรับแต่ง Identity สำหรับการใช้งานที่ซับซ้อนมากขึ้น ดังนั้นคุณจึงต้องการหลีกเลี่ยงวิธีการมิดเดิลแวร์ที่คุณกล่าวถึงข้างต้นและมุ่งสู่บริการ ทำตามขั้นตอนการย้ายข้อมูลในบทความที่อ้างอิงเพื่อให้บรรลุเป้าหมายนี้ เริ่มต้นด้วยการเปลี่ยนapp.UseIdentityกับapp.UseAuthentication UseIdentityเป็นค่าเสื่อมราคาและจะไม่รองรับในเวอร์ชันอนาคต สำหรับตัวอย่างที่สมบูรณ์ของวิธีแทรกการเปลี่ยนแปลงการอ้างสิทธิ์ที่กำหนดเองและดำเนินการให้สิทธิ์ในการอ้างสิทธิ์ดูโพสต์บล็อกนี้


12
มีตัวอย่างวิธีใช้กับแอป WebAPI หรือไม่?
alexb
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.