การอ่าน AuthorizationFilterContext ใน netcore api 3.1


9

ฉันมีโครงการ netcore 2.2 ที่ใช้งานได้ซึ่งฉันได้นำนโยบายที่กำหนดเองมาใช้เพื่อตรวจสอบคีย์ API

ใน startup.cs ฉันกำลังเพิ่มนโยบายนี้เช่นนี้

//Add Key Policy
services.AddAuthorization(options =>
{
    options.AddPolicy("AppKey", policy => policy.Requirements.Add(new AppKeyRequirement()));
});

ใน AppKeyRequirement ฉันสืบทอดมาจาก AuthorizationHandler และแก้ไขคีย์ในคำขอที่เข้ามาเช่นนี้

protected override Task HandleRequirementAsync(AuthorizationHandlerContext authContext, AppKeyRequirement requirement)
{
    var authorizationFilterContext = (AuthorizationFilterContext)authContext.Resource;
    var query = authorizationFilterContext.HttpContext.Request.Query;

    if (query.ContainsKey("key") && query.ContainsKey("app"))
    { // Do stuff

สิ่งนี้ไม่ทำงานใน netcore 3.1

ฉันได้รับข้อผิดพลาดต่อไปนี้:

ไม่สามารถโยนวัตถุประเภท 'Microsoft.AspNetCore.Routing.RouteEndpoint' เพื่อพิมพ์ 'Microsoft.AspNetCore.Mvc.Filters.AuthorizationFilterContext'

วิธีที่ถูกต้องในการทำเช่นนี้ใน core 3 ขึ้นไปคืออะไร?

ดังที่ Kirk Larkin ชี้ให้เห็นวิธีที่ถูกต้องใน. net 3.0 และสูงกว่าคือการฉีด IHttpContextAccessor เข้าไปในตัวจัดการ Auth และใช้สิ่งนั้น

คำถามของฉัน ณ จุดนี้ฉันจะฉีดนี้ได้อย่างไร ฉันไม่สามารถผ่านสิ่งนี้ใน startup.cs หรืออย่างน้อยฉันไม่เห็นว่า

ความคิด / คำแนะนำใด ๆ ที่จะได้รับการชื่นชมมาก

คำตอบ:


14

ในเวอร์ชันก่อนหน้า ASP.NET Core 3.0 การใช้งานของIAuthorizationHandlerถูกเรียกใช้ในระหว่างไปป์ไลน์ MVC ใน 3.0 เป็นต้นไปซึ่งใช้การกำหนดเส้นทางปลายทาง (โดยค่าเริ่มต้น) การใช้งานเหล่านี้จะถูกเรียกใช้โดยมิดเดิลแวร์การอนุญาต ( UseAuthorization()) มิดเดิลแวร์นี้ทำงานก่อนขั้นตอนการทำงานของ MVC แทนที่จะเป็นส่วนหนึ่ง

การเปลี่ยนแปลงนี้หมายความว่าAuthorizationFilterContextจะไม่ถูกส่งผ่านไปยังตัวจัดการการอนุญาตอีกต่อไป แต่เป็นตัวอย่างของการที่ไม่ให้เข้าถึงRouteEndpointHttpContext

ในตัวอย่างของคุณคุณจะใช้AuthorizationFilterContextเพื่อรับHttpContextเท่านั้น ใน 3.0+ ให้แทรกIHttpContextAccessorตัวจัดการการอนุญาตของคุณแล้วใช้มัน นี่คือตัวอย่างของความสมบูรณ์:

public class AppKeyAuthorizationHandler : AuthorizationHandler<AppKeyRequirement>
{
    private readonly IHttpContextAccessor httpContextAccessor;

    public AppKeyAuthorizationHandler(IHttpContextAccessor httpContextAccessor)
    {
        this.httpContextAccessor = httpContextAccessor;
    }

    protected override Task HandleRequirementAsync(
        AuthorizationHandlerContext authContext, AppKeyRequirement requirement)
    {
        var httpContext = httpContextAccessor.HttpContext;
        var query = httpContext.Request.Query;

        if (query.ContainsKey("key") && query.ContainsKey("app"))
        {
            // ...
        }
    }
}

คุณอาจต้องลงทะเบียนIHttpContextAccessorในConfigureServices:

services.AddHttpContextAccessor();

ดูการใช้ HttpContext จากองค์ประกอบที่กำหนดเองIHttpContextAccessorสำหรับข้อมูลเพิ่มเติมเกี่ยวกับการใช้


1
ขอบคุณสำหรับคำแนะนำนี้ ฉันกำลังพยายามสร้างนโยบายที่หากคีย์ API หายไปการโทรจะถูกปฏิเสธ เราไม่สามารถใช้ // เพิ่มบริการนโยบายคีย์ได้อีกต่อไปเพิ่ม (ตัวเลือก => {options.AddPolicy ("AppKey", นโยบาย => policy.Requirements.Add (ใหม่ AppKeyRequirement ());}); ถ้าไม่ฉันจะตัดการโทรก่อนที่มันจะกระทบการกระทำของคอนโทรลเลอร์ได้อย่างไร?
w2olves

1
ใช่มันยังคงใช้ได้เหมือนเดิม
Kirk Larkin

ตัวสร้างกำลังคาดหวังว่า IHttpContextAccessor ฉันจะผ่านสิ่งนี้ได้อย่างไรเมื่อฉันสร้างนโยบายใน Startup.cs services.AddAuthorization (options => {options.AddPolicy ("AppKey", policy => policy.Requirements.Add (AppKeyRequirement ใหม่) ());}); ฉันยังสามารถสร้างตัวสร้างเริ่มต้นใหม่สำหรับ AppKeyAuthorizationHandler แต่จากนั้น httpContextAccessor.HttpContext; เป็นโมฆะเมื่อมีคำขอเข้ามาแนวคิดใด ๆ
w2olves

1
คุณสามารถเพิ่มการจัดการของคุณโดยใช้ DI IHttpContextAccessorซึ่งจะสร้างตัวอย่างของมันสำหรับคุณและผ่านไปใน ดูเอกสาร
Kirk Larkin
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.