แนวทางปฏิบัติที่ดีที่สุดสำหรับบทบาทเทียบกับข้อเรียกร้องใน ASP.NET Identity


98

ผมใหม่ที่สมบูรณ์แบบที่จะใช้claimsในและต้องการที่จะได้รับความคิดของการปฏิบัติที่ดีที่สุดในการใช้งานของASP.NETIdentityRoles and/or Claims

หลังจากอ่านทั้งหมดนี้ฉันยังคงมีคำถามเช่น ...

ถาม: เราไม่ใช้ Roles อีกต่อไปหรือไม่?
ถาม: ถ้าเป็นเช่นนั้นเหตุใดจึงยังคงเสนอบทบาท
ถาม: เราควรใช้การอ้างสิทธิ์เท่านั้นหรือไม่
ถาม: เราควรใช้ Roles & Claims ร่วมกันหรือไม่?

ความคิดเริ่มต้นของฉันคือเรา "ควร" ใช้ร่วมกัน ฉันเห็นClaimsว่าเป็นหมวดหมู่ย่อยที่Rolesพวกเขารองรับ

สำหรับตัวอย่าง:
บทบาท:การ
อ้างสิทธิ์ทางบัญชี: CanUpdateLedger, CanOnlyReadLedger, CanDeleteFromLedger

ถาม: พวกเขาตั้งใจที่จะใช้ร่วมกันหรือไม่?
ถาม: หรือจะเป็นการดีกว่าที่จะอ้างสิทธิ์เท่านั้นและ "มีคุณสมบัติครบถ้วน" ที่คุณอ้างสิทธิ์
ถาม: แนวทางปฏิบัติที่ดีที่สุดคืออะไร

ตัวอย่าง: การใช้ Roles & Claims ร่วมกัน
แน่นอนคุณจะต้องเขียน Attribute logic ของคุณเองสำหรับสิ่งนี้ ...

[Authorize(Roles="Accounting")]
[ClaimAuthorize(Permission="CanUpdateLedger")]
public ActionResult CreateAsset(Asset entity)
{
    // Do stuff here

    return View();
}

ตัวอย่าง: การอ้างสิทธิ์ของคุณอย่างครบถ้วน

[ClaimAuthorize(Permission="Accounting.Ledger.CanUpdate")]
public ActionResult CreateAsset(Asset entity)
{
    // Do stuff here

    return View();
}

1
ตอนนี้ฉันกำลังเผชิญกับปัญหาเดียวกันคุณจะแก้ปัญหาอย่างไรและคุณสามารถ subRole the Permission ในแอปพลิเคชันได้อย่างไร
เลย

คำตอบ:


78

บทบาทคือหมวดหมู่เชิงสัญลักษณ์ที่รวบรวมผู้ใช้ที่ใช้สิทธิ์ความปลอดภัยในระดับเดียวกัน การให้สิทธิ์ตามบทบาทจำเป็นต้องระบุผู้ใช้ก่อนจากนั้นตรวจสอบบทบาทที่ผู้ใช้ได้รับมอบหมายจากนั้นจึงเปรียบเทียบบทบาทเหล่านั้นกับบทบาทที่ได้รับอนุญาตให้เข้าถึงทรัพยากร

ในทางตรงกันข้ามการอ้างสิทธิ์ไม่ได้อิงตามกลุ่ม แต่เป็นการอ้างตัวตน

จากเอกสารของ Microsoft :

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

การตรวจสอบความปลอดภัยในภายหลังสามารถกำหนดสิทธิ์ในการเข้าถึงทรัพยากรตามมูลค่าของการอ้างสิทธิ์หนึ่งรายการขึ้นไป

คุณสามารถใช้ทั้งสองแบบในคอนเสิร์ตหรือใช้ประเภทหนึ่งในบางสถานการณ์และอีกประเภทในสถานการณ์อื่น ๆ ส่วนใหญ่ขึ้นอยู่กับการดำเนินการระหว่างกันกับระบบอื่น ๆ และกลยุทธ์การจัดการของคุณ ตัวอย่างเช่นผู้จัดการอาจจัดการรายชื่อผู้ใช้ที่กำหนดให้กับบทบาทได้ง่ายกว่าที่จะจัดการว่าใครมีการกำหนดข้อเรียกร้องที่เฉพาะเจาะจง การอ้างสิทธิ์จะมีประโยชน์มากในสถานการณ์ที่ไม่พึงประสงค์ซึ่งคุณสามารถกำหนดการอ้างสิทธิ์ให้กับลูกค้าจากนั้นลูกค้าจะสามารถยื่นคำร้องเพื่อขออนุมัติแทนที่จะส่งชื่อผู้ใช้และรหัสผ่านสำหรับทุกคำขอ


7
ฉันไม่เชื่อว่ามันถูกต้องทั้งหมด ฉันเชื่อว่าการอ้างสิทธิ์บ่งบอกตัวตนไม่ใช่การอนุญาต สิ่งที่พวกเขาได้รับอนุญาตให้ทำจะถูกจัดการแยกกัน นั่นคือพวกเขาอาจมีการอ้างสิทธิ์ที่มีวันเดือนปีเกิดระบุว่าพวกเขามีอายุเกิน 18 ปีการอ้างสิทธิ์นี้จะถูกส่งต่อไปยัง Authorization Manager ซึ่งอาจมีกฎที่ระบุว่า "ถ้าพวกเขามีอายุมากกว่า 18 ปีพวกเขาสามารถแก้ไขทรัพยากร X ได้" แต่การอ้างสิทธิ์นั้นไม่ได้ระบุถึงสิ่งที่พวกเขาทำได้ / ไม่สามารถทำได้หรือเข้าถึง เช่นเดียวกันกับบทบาทและการอ้างสิทธิ์อื่น ๆ ข้อเรียกร้องบ่งบอกว่าคุณเป็นใครและใช้เพื่อกำหนดสิ่งที่คุณทำได้ แต่ไม่ได้บอกคุณโดยตรง
ChrisC

เอกสารประกอบสำหรับ @ChrisC มาจากการอนุญาตตามการอ้างสิทธิ์ของ Microsoft ใน ASP.NET Core : "การอ้างสิทธิ์คือคู่ค่าของชื่อที่แสดงถึงสิ่งที่เป็นเรื่องไม่ใช่สิ่งที่หัวเรื่องสามารถทำได้"
DrGriff

@DrGriff ขอบคุณที่ให้ลิงค์; ฉันตั้งคำถามมาระยะหนึ่งแล้วเกี่ยวกับความถูกต้องของคำอธิบายที่ฉันให้ไว้ ฉันคิดว่าฉันได้ชี้แจงคำตอบตามลิงค์นั้นแล้ว
Claies

31

ดังที่ @Claies อธิบายอย่างสมบูรณ์แบบการอ้างสิทธิ์อาจเป็นคำอธิบายได้มากกว่าและเป็นบทบาทที่ลึกซึ้ง ฉันคิดว่าพวกเขาเป็นรหัสบทบาทของคุณ ฉันมีรหัสยิมดังนั้นฉันจึงอยู่ในบทบาทสมาชิก ฉันอยู่ในบทเรียนคิกบ็อกซิ่งด้วยดังนั้นฉันจึงมีการอ้างสิทธิ์รหัสคิกบ็อกซิ่งสำหรับพวกเขา ใบสมัครของฉันจะต้องมีการประกาศบทบาทใหม่เพื่อให้เหมาะสมกับสิทธิการเป็นสมาชิกของฉัน แต่ฉันมีรหัสสำหรับแต่ละคลาสกลุ่มที่ฉันเป็นสมาชิกแทนที่จะเป็นประเภทสมาชิกใหม่ ๆ นั่นคือเหตุผลที่การอ้างสิทธิ์เหมาะสมกับฉันมากกว่า

มีวิดีโอคำอธิบายที่ยอดเยี่ยมเกี่ยวกับ Barry Dorrans ซึ่งพูดถึงข้อดีของการใช้การอ้างสิทธิ์เหนือบทบาท นอกจากนี้เขายังระบุว่าบทบาทยังคงอยู่ใน. NET เพื่อความเข้ากันได้แบบย้อนหลัง วิดีโอนี้ให้ข้อมูลเกี่ยวกับวิธีการอ้างสิทธิ์บทบาทนโยบายการอนุญาตและการตรวจสอบสิทธิ์

คุณสามารถค้นหาได้ที่นี่: ASP.NET Core Authorization with Barr Dorrans


8

ด้วยการใช้เทคนิคการพิสูจน์ตัวตนและการอนุญาตต่างๆมานานหลายทศวรรษแอปพลิเคชัน MVC ปัจจุบันของฉันใช้วิธีการดังต่อไปนี้

การอ้างสิทธิ์ใช้สำหรับการอนุญาตทั้งหมด ผู้ใช้จะได้รับมอบหมายหนึ่งบทบาท (สามารถทำได้หลายบทบาท แต่ฉันไม่ต้องการสิ่งนี้) - เพิ่มเติมด้านล่าง

ตามหลักปฏิบัติทั่วไปจะใช้คลาสแอตทริบิวต์ ClaimsAuthorize เนื่องจากการกระทำของตัวควบคุมส่วนใหญ่เป็น CRUD ฉันจึงมีกิจวัตรในการสร้างฐานข้อมูลรหัสแรกที่วนซ้ำการดำเนินการของตัวควบคุมทั้งหมดและสร้างประเภทการอ้างสิทธิ์สำหรับแอตทริบิวต์การดำเนินการของคอนโทรลเลอร์แต่ละรายการของ Read / Edit / Create / Delete เช่นจาก

[ClaimsAuthorize("SomeController", "Edit")]
[HttpPost]

สำหรับการใช้งานในมุมมอง MVC คลาสคอนโทรลเลอร์พื้นฐานจะแสดงรายการกระเป๋า

        protected override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            // get user claims
            var user = filterContext.HttpContext.User as System.Security.Claims.ClaimsPrincipal;

            if (user != null)
            {
                // Get all user claims on this controller. In this controler base class, [this] still gets the descendant instance type, hence name
                List<Claim> claims = user.Claims.Where(c => c.Type == this.GetType().Name).ToList();

                // set Viewbag with default authorisations on this controller
                ViewBag.ClaimRead = claims.Any(c => c.Value == "Read");
                ViewBag.ClaimEdit = claims.Any(c => c.Value == "Edit");
                ViewBag.ClaimCreate = claims.Any(c => c.Value == "Create");
                ViewBag.ClaimDelete = claims.Any(c => c.Value == "Delete");
            }

            base.OnActionExecuting(filterContext);
        }

สำหรับเมนูเว็บไซต์และการดำเนินการอื่น ๆ ที่ไม่ใช่ตัวควบคุมฉันมีการอ้างสิทธิ์อื่น ๆ เช่นผู้ใช้สามารถดูช่องทางการเงินที่เฉพาะเจาะจงได้หรือไม่

bool UserHasSpecificClaim(string claimType, string claimValue)
{
    // get user claims
    var user = this.HttpContext.User as System.Security.Claims.ClaimsPrincipal;

    if (user != null)
    {
        // Get the specific claim if any
        return user.Claims.Any(c => c.Type == claimType && c.Value == claimValue);
    }

    return false;
}

public bool UserHasTradePricesReadClaim
{
    get
    {
        return UserHasSpecificClaim("TradePrices", "Read");
    }
}

แล้วบทบาทไหนเหมาะสม?

ฉันมีตารางที่เชื่อมโยงบทบาทกับชุดการอ้างสิทธิ์ (ค่าเริ่มต้น) เมื่อตั้งค่าการอนุญาตผู้ใช้ค่าเริ่มต้นคือให้ผู้ใช้อ้างสิทธิ์ในบทบาทของตน ผู้ใช้แต่ละคนสามารถอ้างสิทธิ์ได้มากกว่าหรือน้อยกว่าค่าเริ่มต้น เพื่อให้การแก้ไขเป็นเรื่องง่ายรายการการอ้างสิทธิ์จะแสดงโดยตัวควบคุมและการดำเนินการ (ในแถว) พร้อมด้วยการอ้างสิทธิ์อื่น ๆ จะแสดงรายการ ปุ่มต่างๆใช้ร่วมกับ Javascript เพื่อเลือกชุดการดำเนินการเพื่อลด "การคลิก" ที่จำเป็นเพื่อเลือกการอ้างสิทธิ์ ในบันทึกการอ้างสิทธิ์ของผู้ใช้จะถูกลบและเพิ่มการอ้างสิทธิ์ที่เลือกทั้งหมด เว็บแอปพลิเคชันโหลดการอ้างสิทธิ์เพียงครั้งเดียวดังนั้นการเปลี่ยนแปลงใด ๆ ต้องแจ้งให้โหลดซ้ำภายในข้อมูลคงที่นี้

ผู้จัดการจึงสามารถเลือกได้ว่าจะอ้างสิทธิ์ใดในแต่ละบทบาทและการอ้างสิทธิ์ที่ผู้ใช้มีหลังจากตั้งค่าเป็นบทบาทและการอ้างสิทธิ์เริ่มต้นเหล่านั้น ระบบมีผู้ใช้เพียงเล็กน้อยดังนั้นการจัดการข้อมูลนี้จึงเป็นไปอย่างตรงไปตรงมา


4

เพื่อให้เข้าใจถึงความแตกต่างระหว่างบทบาทและการอ้างสิทธิ์ที่คุณเสากระโดงต้องเผชิญกับข้อ จำกัด ของบทบาทและรู้สึกว่าการอ้างสิทธิ์เข้ามาแก้ไขปัญหานี้ได้อย่างไรฉันจึงขอเสนอ 2 สถานการณ์ให้คุณรับรู้ถึงพลังของการอ้างสิทธิ์ที่บทบาทไม่สามารถแก้ไขปัญหานี้ได้:

1- ไซต์ของคุณต้องมีสองโมดูล (หน้าบริการ .. ฯลฯ ) โมดูลแรกสำหรับเด็ก (อายุต่ำกว่า 18 ปี) อีกโมดูลสำหรับผู้ใหญ่ (อายุมากกว่า 18 ปี) ข้อมูลประจำตัวผู้ใช้ของคุณมีการอ้างสิทธิ์วันเกิด

คุณต้องสร้างนโยบายเกี่ยวกับการอ้างสิทธิ์นี้เพื่อให้การอนุญาตสำหรับแต่ละโมดูลจะได้รับตามค่านี้และหากอายุของผู้ใช้มาเกิน 18 ปีเขาสามารถไปที่โมดูลสำหรับผู้ใหญ่ได้และไม่ใช่ก่อนอายุนี้

บทบาทคือประเภทข้อมูลบูลีนที่คุณสามารถมีหรือไม่มีบทบาทไม่มีค่ามัลตี

2- ไซต์ของคุณมีผู้ใช้ตามบทบาทและคุณไม่ต้องการป้องกันการเข้าถึงของผู้ใช้เพื่อทำการบำรุงรักษาโดยไม่ต้องเปลี่ยนรหัส

ในการอ้างสิทธิ์คุณสามารถสร้างนโยบาย UnderConstrain ว่าหากผู้ใช้จริงไม่สามารถดูเพจได้ให้สิทธิ์คุณสมบัติสำหรับผู้ใช้บทบาท

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