Nhận người dùng hiện tại, trong một hành động ApiController, mà không chuyển userID làm tham số


97

Làm cách nào để chúng tôi có được người dùng hiện tại, trong một hành động ApiController an toàn, mà không chuyển userName hoặc userId làm tham số?

Chúng tôi giả định rằng điều này có sẵn, vì chúng tôi đang thực hiện một hành động an toàn. Đang thực hiện một hành động an toàn có nghĩa là người dùng đã xác thực và yêu cầu có mã thông báo mang tên của cô ấy. Cho rằng WebApi đã ủy quyền cho người dùng, có thể có một cách được xây dựng để truy cập userId mà không cần phải chuyển nó dưới dạng tham số hành động.


Xin vui lòng, thấy trả lời này: stackoverflow.com/a/26453782/3290276 Thêm yêu cầu bồi thường đã làm các trick
Gabriela Macias

Câu trả lời:


149

Trong WebApi 2, bạn có thể sử dụng RequestContext.Principaltừ bên trong một phương thức trên ApiController


1
Có vẻ như chúng tôi không có tài sản đó. Hừ! Có thể chúng tôi đang sử dụng phiên bản WebApi cũ.
Shaun Luttin

2
@ShaunLuttin Ok, vì vậy nếu bạn đang sử dụng Web API 1 thì tôi tin rằng có một thuộc tính Prinicpal trên ApiController. Đây chỉ là một trình bao bọc ưa thích xung quanh việc truy cập bộ sưu tập Request.Properties. Đối tượng chính được lưu trữ trong từ điển đó.
Darrel Miller

6
Chỉ cần đừng quênusing Microsoft.AspNet.Identity;
Overlord

1
@DarrelMiller có một cách để lấy cùng một (giả sử ngữ cảnh yêu cầu) từ các phần khác của mã (không phải trong bộ điều khiển).
Ajay Aradhya

2
@AjayAradhya Chỉ khi bạn vượt qua nó ở đó. Những nỗ lực trước đây trên các khuôn khổ web đã chỉ ra rằng việc sử dụng thuộc tính tĩnh để truy cập vào ngữ cảnh yêu cầu gây ra tất cả các loại vấn đề về kiến ​​trúc. Thoạt đầu thì thuận tiện nhưng về lâu dài sẽ gây ra nhiều đau đớn.
Darrel Miller

36

Bạn cũng có thể truy cập chính bằng cách sử dụng Usertài sản trên ApiController.

Vì vậy, hai câu lệnh sau về cơ bản giống nhau:

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

15
Tôi đang cố gắng sử dụng những gì bạn đã viết ở đây nhưng hàm GetUserId () luôn trả về null. Người dùng được xác thực, tôi đang chuyển một mã thông báo mang tên và ApiController có tiêu đề [Authorize]
Joshua Ohana

Hàm GetUserId () chỉ trả về một ID nếu người dùng có yêu cầu về NameIdentifier. Để biết ví dụ về cách giải quyết vấn đề này, hãy tham khảo câu trả lời của Oswaldo tại đây: stackoverflow.com/questions/19505526
jramm

14

Gợi ý nằm trong bộ điều khiển tài khoản được tạo tự động Webapi2

Có thuộc tính này với getter được định nghĩa là

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

và để có được UserManager - Trong WebApi2 -do as Romans (đọc là AccountController) làm

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

Điều này phải tương thích trong IIS và chế độ tự lưu trữ


7

Không có gợi ý nào ở trên phù hợp với tôi. Sau đây đã làm!

HttpContext.Current.Request.LogonUserIdentity.Name

Tôi đoán có rất nhiều kịch bản khác nhau và kịch bản này phù hợp với tôi. Kịch bản của tôi liên quan đến giao diện người dùng AngularJS và ứng dụng phụ trợ Web API 2, cả hai đều chạy dưới IIS. Tôi đã phải đặt cả hai ứng dụng để chạy riêng trong Windows Authentication.

Không cần phải chuyển bất kỳ thông tin người dùng nào. Trình duyệt và IIS trao đổi thông tin đăng nhập của người dùng và API Web có quyền truy cập vào thông tin đăng nhập của người dùng theo yêu cầu (từ IIS I giả định).


6

Câu trả lời của Karan Bhandari là tốt, nhưng AccountController được thêm vào trong một dự án rất có thể là a Mvc.Controller. Để chuyển đổi câu trả lời của anh ấy để sử dụng trong ApiController, hãy thay đổi HttpContext.Current.GetOwinContext()thành Request.GetOwinContext()và đảm bảo rằng bạn đã thêm 2 usingcâu lệnh sau:

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


3

Nếu bạn đang sử dụng Asp.Identity UseManager, nó sẽ tự động đặt giá trị của

RequestContext.Principal.Identity.GetUserId ()

dựa trên IdentityUser mà bạn sử dụng để tạo IdentityDbContext .

Nếu bạn đang triển khai bảng người dùng tùy chỉnh và xác thực người mang mã thông báo owin, vui lòng kiểm tra câu trả lời của tôi.

Làm thế nào để lấy ngữ cảnh người dùng trong các cuộc gọi Web Api?

Hy vọng nó vẫn giúp ích. :)


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();
}

Hoặc dựa trên nhận xét của Darrel Miller, có thể sử dụng điều này để lấy HttpContext trước.

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

Xem thêm:

Cách truy cập HTTPContext từ bên trong hành động API Web của bạn


5
Không sử dụng HttpContext vì nó giới hạn các tùy chọn lưu trữ của bạn và khiến mã của bạn khó kiểm tra.
Darrel Miller

Các đối tượng HttpContext sẽ không có trong từ điển nếu bạn đang tự chủ, hoặc OwinHttpListener tổ chức
Darrel Miller
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.