รับผู้ใช้ปัจจุบันภายในแอ็คชัน ApiController โดยไม่ต้องส่ง userID เป็นพารามิเตอร์


97

เราจะรับผู้ใช้ปัจจุบันภายในแอ็คชัน ApiController ที่ปลอดภัยได้อย่างไรโดยไม่ส่ง userName หรือ userId เป็นพารามิเตอร์

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


โปรดดูคำตอบนี้: stackoverflow.com/a/26453782/3290276เพิ่มการอ้างสิทธิ์ทำเคล็ดลับ
Gabriela Macias

คำตอบ:


149

ใน WebApi 2 คุณสามารถใช้RequestContext.Principalจากภายในเมธอดบน ApiController


1
ดูเหมือนว่าเราไม่มีทรัพย์สินนั้น อืม. บางทีเราอาจใช้ WebApi เวอร์ชันเก่า
Shaun Luttin

2
@ShaunLuttin ตกลงดังนั้นหากคุณใช้ Web API 1 แล้วคุณเชื่อว่ามีคุณสมบัติ Prinicpal บน ApiController นี่เป็นเพียงกระดาษห่อหุ้มแฟนซีในการเข้าถึงคอลเลกชัน Request.Properties อ็อบเจ็กต์หลักจะถูกเก็บไว้ในพจนานุกรมนั้น
Darrel Miller

6
อย่าลืมusing Microsoft.AspNet.Identity;
Overlord

1
@DarrelMiller มีวิธีในการรับสิ่งเดียวกัน (พูดบริบทคำขอ) จากส่วนอื่น ๆ ของโค้ด (ไม่ใช่ภายในคอนโทรลเลอร์)
Ajay Aradhya

2
@AjayAradhya ถ้าคุณผ่านมันไปที่นั่น ความพยายามก่อนหน้านี้ในเว็บเฟรมเวิร์กแสดงให้เห็นว่าการใช้คุณสมบัติคงที่เพื่อเข้าถึงบริบทคำขอทำให้เกิดปัญหาทางสถาปัตยกรรมทุกประเภท สะดวกในตอนแรก แต่ทำให้ปวดมากในระยะยาว
Darrel Miller

36

นอกจากนี้คุณยังสามารถเข้าถึงหลักโดยใช้ทรัพย์สินในUserApiController

ดังนั้นสองคำสั่งต่อไปนี้จึงเหมือนกันโดยทั่วไป:

string id;
id = User.Identity.GetUserId();
id = RequestContext.Principal.Identity.GetUserId();

15
ฉันพยายามใช้สิ่งที่คุณเขียนไว้ที่นี่ แต่ฟังก์ชัน GetUserId () จะคืนค่า null เสมอ ผู้ใช้ได้รับการรับรองความถูกต้องฉันกำลังส่งโทเค็นผู้ถือและ ApiController มีส่วนหัว [Authorize]
Joshua Ohana

ฟังก์ชัน GetUserId () ส่งคืน ID ก็ต่อเมื่อผู้ใช้มีการอ้างสิทธิ์ NameIdentifier สำหรับตัวอย่างวิธีแก้ไขปัญหานี้โปรดดูคำตอบของ Oswaldo ที่นี่: stackoverflow.com/questions/19505526
jramm

14

คำแนะนำอยู่ในตัวควบคุมบัญชีที่สร้างขึ้นโดยอัตโนมัติของ Webapi2

มีคุณสมบัตินี้ด้วย getter กำหนดเป็น

public string UserIdentity
        {
            get
            {
                var user = UserManager.FindByName(User.Identity.Name);
                return user;//user.Email
            }
        }

และเพื่อให้ได้ UserManager - ใน WebApi2 -do เป็นภาษาโรมัน (อ่านว่า AccountController) ทำ

public ApplicationUserManager UserManager
        {
            get { return HttpContext.Current.GetOwinContext().GetUserManager<ApplicationUserManager>(); }
        }

สิ่งนี้ควรเข้ากันได้ใน IIS และโหมดโฮสต์ตนเอง


7

คำแนะนำข้างต้นไม่ได้ผลสำหรับฉัน ต่อไปนี้ได้!

HttpContext.Current.Request.LogonUserIdentity.Name

ฉันเดาว่ามีหลายสถานการณ์และสถานการณ์นี้เหมาะกับฉัน สถานการณ์ของฉันเกี่ยวข้องกับส่วนหน้า AngularJS และแอปพลิเคชันแบ็กเอนด์ Web API 2 ซึ่งทำงานภายใต้ IIS ผมต้องตั้งค่าทั้งการใช้งานเพื่อให้ทำงานได้เฉพาะภายใต้ Windows รับรองความถูกต้อง

ไม่ต้องส่งผ่านข้อมูลผู้ใช้ใด ๆ เบราว์เซอร์และ IIS แลกเปลี่ยนข้อมูลรับรองผู้ใช้ที่ล็อกออนและ Web API สามารถเข้าถึงข้อมูลรับรองของผู้ใช้ตามความต้องการ (จาก IIS ฉันสันนิษฐาน)


6

คำตอบของ Karan Bhandari นั้นดี แต่ AccountController ที่เพิ่มเข้ามาในโปรเจ็กต์นั้นมีโอกาสมากที่จะเป็นMvc.Controllerไฟล์. ในการแปลงคำตอบสำหรับใช้ใน ApiController HttpContext.Current.GetOwinContext()ให้เปลี่ยนเป็นRequest.GetOwinContext()และตรวจสอบให้แน่ใจว่าคุณได้เพิ่ม 2 usingคำสั่งต่อไปนี้:

using Microsoft.AspNet.Identity;
using Microsoft.AspNet.Identity.Owin;

5

ใน. Net Core ใช้User.Identity.Nameเพื่อรับการอ้างสิทธิ์ชื่อของผู้ใช้


2
User.Identity.Nameได้รับมูลค่าของการอ้างสิทธิ์ชื่อ ไม่ใช่เฉพาะ Active Directory
Nate Barbettini

@Nate ขอบคุณสำหรับความคิดเห็นของคุณฉันได้แก้ไขแล้ว
Venkatesh Muniyandi

3

หากคุณใช้ Asp.Identity UseManager โปรแกรมจะตั้งค่าโดยอัตโนมัติ

RequestContext.Principal.Identity.GetUserId ()

ขึ้นอยู่กับIdentityUserคุณใช้ในการสร้างIdentityDbContext

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

จะรับบริบทของผู้ใช้ระหว่างการโทร Web Api ได้อย่างไร

หวังว่ามันจะยังช่วยได้ :)


1
string userName;
string userId;
if (HttpContext.Current != null && HttpContext.Current.User != null 
        && HttpContext.Current.User.Identity.Name != null)
{
    userName = HttpContext.Current.User.Identity.Name;
    userId = HttpContext.Current.User.Identity.GetUserId();
}

หรือตามความคิดเห็นของ Darrel Miller อาจใช้สิ่งนี้เพื่อดึง HttpContext ก่อน

// get httpContext
object httpContext;
actionContext.Request.Properties.TryGetValue("MS_HttpContext", out httpContext);    

ดูสิ่งนี้ด้วย:

วิธีเข้าถึง HTTPContext จากภายในการดำเนินการ Web API ของคุณ


5
อย่าใช้ HttpContext เนื่องจาก จำกัด ตัวเลือกโฮสติ้งของคุณและทำให้โค้ดของคุณทดสอบได้ยาก
Darrel Miller

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