5

Tôi đã đọc rất nhiều câu hỏi và câu trả lời về chủ đề này, nhưng không có câu hỏi nào trong số họ đã giúp tôi giải quyết vấn đề này.IPrincipal tùy chỉnh không thể truy cập trong MVC5

Sự cố tôi gặp phải là thuộc tính HttpContext.Current.User hoặc chỉ User thuộc loại RolePrincipal thay vì hiệu trưởng tùy chỉnh của tôi.

Đây là ứng dụng web MVC 5 sử dụng Xác thực Windows (ứng dụng chỉ mạng nội bộ). Hiệu trưởng tùy chỉnh của tôi là một lớp con của WindowsPrincipal và tôi đã triển khai RoleProvider của riêng mình để sử dụng trong thẻ thuộc tính ủy quyền.

Khi tôi cố gắng sử dụng hiệu trưởng bằng cách truyền cho hiệu trưởng tùy chỉnh của tôi từ IPrincipal trên HttpContext hiện tại, tôi nhận được thông báo lỗi của loại RolePrincipal, điều này rõ ràng không thể được gửi cho hiệu trưởng tùy chỉnh của tôi. Tôi đang thiết yếu tùy chỉnh của tôi trong trường hợp Application_PostAuthenticationRequest:

protected void Application_PostAuthenticationRequest(object sender, EventArgs e) 
{ 
    if (User == null) 
     return; 

    using(EntityContext db = new EntityContext()) 
    { 
     var user = db.Users.SingleOrDefault(u => u.ADName.Equals(User.Identity.Name)); 
     HttpContext.Current.User = new PcsPrincipal((WindowsIdentity)User.Identity, user); 
    } 
} 

Khi tôi đặt một breakpoint trong phương pháp mà nó dường như không bao giờ được gọi, mà có thể giải thích lý do tại sao nó không nhận được thiết lập để chính tùy chỉnh của tôi.

Tôi đã xem xét QA sau, nhưng họ đã không thể giải quyết vấn đề:

Tôi đang làm gì sai để không có bộ chính? Hãy cho tôi biết nếu cần thêm mã.

EDIT: Đặt HttpContext.Current.User thành hiệu trưởng tùy chỉnh của tôi trong sự kiện WindowsAuthentication.OnAuthenticate không giải quyết vấn đề này. Hành vi tương tự chính xác được trưng bày bằng phương pháp đó.

Trả lời

1

Sau khi liên tục nghiên cứu vấn đề này cuối cùng tôi đã tìm thấy câu trả lời bằng một câu hỏi SO làm cho tôi loại câu hỏi của một trùng lặp: MVC3 Windows Authentication override User.Identity

Dưới đây là câu trả lời đăng bởi @Toby Jones (như là một chỉnh sửa để câu hỏi ban đầu của anh ấy) dẫn đến việc tôi giải quyết vấn đề của mình, nhưng câu trả lời của anh ấy thực sự là tập hợp của hai câu trả lời được đăng bởi @Erik Funkenbusch & @Darin Dimitrov. Câu trả lời được chỉnh sửa để sửa một số ngữ pháp & để xóa một số thông tin thừa.

Tùy chọn 1: Ghi đè yêu cầu ủy quyền trong toàn cầu.asax

Sự kiện Application_AuthenticateRequest không nên được sử dụng vì (HttpContext.Current.User là null mặc dù Windows Authentication được bật) người dùng chưa được điền trong quá trình xác thực Windows và do đó không có gì tôi có thể sử dụng để lấy người dùng thông tin.

Application_AuthorizeRequest là tiếp theo trong chuỗi và sẽ xảy ra sau khi WindowsIdentity được đưa vào

protected void Application_AuthorizeRequest(object sender, EventArgs e) 
{ 
    if (User.Identity.IsAuthenticated && Roles.Enabled) 
    { 
     Context.User = new CustomPrincipal((WindowsIdentity)User.Identity); 
    } 
} 

Phương án 2:. Ghi đè AuthorizeAttribute

Dưới đây là ghi đè của Authorize Attribute

public class CAuthorize : AuthorizeAttribute 
{ 
    protected override bool AuthorizeCore(HttpContextBase httpContext) 
    { 
     bool authorized = base.AuthorizeCore(httpContext); 
     if (!authorized) 
      return false; 

     IIdentity user = httpContext.User.Identity; 
     CPrincipal cPrincipal = new CPrincipal(user); 
     httpContext.User = cPrincipal; 

     return true; 
    } 
} 

Sau đó thay thế tất cả AuthorizeAttributes thành phiên bản tùy chỉnh.

Tùy chọn 1 xử lý mọi thứ trên toàn cầu, trong khi Tùy chọn 2 xử lý mọi thứ ở cấp độ cá nhân hơn bằng bộ lọc.

Cá nhân, tôi đã chọn sử dụng phương pháp global.asax để tôi có sẵn trụ sở chính trên toàn cầu. Dưới đây là mã thực tế đã giải quyết vấn đề của tôi:

protected void Application_AuthorizeRequest(object source, EventArgs e) 
{ 
    if(User.Identity.IsAuthenticated && Roles.Enabled) 
    { 
     using (EntityContext db = new EntityContext()) 
     { 
      var user = db.Users.Include("Roles").SingleOrDefault(u => u.ADName.Equals(User.Identity.Name)); 
      if (user == null) 
       return; 

     PcsPrincipal principal = new PcsPrincipal((WindowsIdentity)User.Identity, user); 
      Context.User = principal; 
     } 
    }    
} 
1

Bạn nên đặt tùy chỉnh chính trong WindowsAuthentication_OnAuthenticate sự kiện xảy ra khi ứng dụng xác thực yêu cầu hiện tại.

protected void WindowsAuthentication_OnAuthenticate(object source, WindowsAuthenticationEventArgs e) 
{ 
    using(EntityContext db = new EntityContext()) 
    { 
     var user = db.Users.SingleOrDefault(u => u.ADName.Equals(e.Identity.Name)); 
     HttpContext.Current.User = new PcsPrincipal(e.Identity, user); 
    } 
} 
+0

Hành vi tương tự được thể hiện bằng sự kiện 'WindowsAuthentication.OnAuthenticate'. – JNYRanger

Các vấn đề liên quan