2013-02-15 15 views
5

Tôi có một ứng dụng MVC được chứng thực Windows với một lớp kho lưu trữ. Tất cả sự tương tác của bộ điều khiển với cơ sở dữ liệu được thực hiện thông qua kho lưu trữ. Mỗi bộ điều khiển có tham chiếu đến kho lưu trữ:Mẫu để thực hiện ủy quyền trong lớp kho lưu trữ của ứng dụng MVC

public class PostController : Controller 
{ 
    private Repository db = new Repository(); 

    [HttpPost] 
    public ActionResult DeletePost(int id) 
    { 
     // Authorize that the user is allowed to delete this post... 

     db.DeletePost(id); 
    } 
} 

Câu hỏi của tôi là liệu có cách nào tốt để chuyển logic ủy quyền của tôi vào tầng lưu trữ hay không. Tôi muốn chức năng Repository.DeletePost() từ chối xóa các bài đăng không được tạo bởi người dùng đã được xác thực. Vấn đề là kho lưu trữ của tôi không biết ai là người dùng được xác thực. Bộ điều khiển biết (thông qua Controller.User).

Chuyển số Controller.User vào hàm xây dựng Repository không hoạt động, bởi vì Controller.User dường như không được xác định tại thời điểm hàm tạo được gọi.

Tôi làm cách nào để thông báo cho Repository người dùng được xác thực là ai? Nó sẽ là tốt nhất để chỉ cần xây dựng các Repository trong mỗi hành động? Hoặc là một ý tưởng tồi để xử lý nó trong lớp kho lưu trữ?

Trả lời

1

Đề xuất tốt từ cả @BigDaddy và @ChrisPratt.

Tôi đã kết thúc việc giải quyết điều này bằng cách tạo bộ điều khiển cơ sở, tương tự như this answer. My lớp điều khiển cơ bản trông giống như:

public class BaseController : Controller 
{ 
    private ILog _log; 
    private Repository _db; 

    protected Repository Db 
    { 
     get 
     { 
      return _db ?? (_db = new Repository(User)); 
     } 
    } 

    protected ILog Log 
    { 
     get 
     { 
      return _log ?? (_log = LogManager.GetLogger(this.GetType())); 
     } 
    } 
} 

Tất cả các bộ điều khiển của tôi kế thừa từ lớp này, và đã xây dựng-trong việc tiếp cận một lười biếng-nạp Repository mà có một tài liệu tham khảo cho người dùng hiện chứng thực.

+0

Đây là những gì im thực sự làm, nhưng tôi cảm thấy nó không có đủ "tách" như bây giờ kho của chúng tôi được gắn với người dùng của chúng tôi, mà có thể là một loại Admin sẽ không thể làm bất cứ điều gì trừ khi bạn đã chiếm cho nó ở mọi bước – Worthy7

1

Chỉ cần làm một cái gì đó như:

db.DeletePostForUser(id, User.Identity.UserId); 

Sau đó, trong kho của bạn:

public void DeletePostForUser(int id, int userId) 
{ 
    var post = context.Posts.SingleOrDefault(m => m.PostId == id && m.User.UserId == userId) 
    if (post != null) 
    { 
     context.Posts.Remove(post); 
     context.SaveChanges(); 
    } 
} 
+0

Đề nghị tốt ... Tôi đã kết thúc với một thứ khác, vì có thể có nhiều lần trong kho của tôi khi tôi muốn biết 'Người dùng' là ai, và tôi muốn tránh thêm nó vào nhiều chữ ký . – Eric

+1

@Chris nhưng repo của chúng tôi có đang thực hiện tác vụ ủy quyền không? – uriDium

+0

Về cơ bản, @uriDium là đúng, kho lưu trữ chỉ để nhận và thiết lập. Họ không ở đó để bảo vệ người dùng đang làm gì. Đó là công việc của miền. Điều gì xảy ra khi bạn đột nhiên cần thực hiện một số thay đổi trong cơ sở dữ liệu của quản trị viên? Ai truy cập nó không quan trọng, nếu bạn muốn hạn chế truy cập thì bạn hạn chế quyền truy cập ở mức thấp hơn trong các bộ điều khiển. Sau đó, lớp dịch vụ (có thể nằm trong bộ điều khiển) sẽ thực hiện công việc xác thực nếu người dùng có thể thực hiện các thay đổi này (ngay cả khi nó liên quan đến việc gọi cơ sở dữ liệu vì một số lý do kỳ lạ) – Worthy7

3

Hoặc là nó một ý tưởng tồi để xử lý nó trong lớp kho?

Tôi nghĩ Bộ điều khiển là nơi tốt hơn cho ủy quyền của bạn. Hãy để kho lưu trữ là một cổng vào dữ liệu và bộ điều khiển là một gatekeeper cho ứng dụng của bạn. Tôi hy vọng sẽ thấy logic ủy quyền/xác thực sớm nhất trong vòng đời càng tốt.

+0

Tôi có thể đánh giá cao điều đó ... Tôi sẽ xem cảm giác đặt logic ủy quyền của tôi trong kho lưu trữ như thế nào. Nếu nó kết thúc cảm thấy bẩn, sau đó tôi có thể sẽ trở lại đề nghị của bạn. – Eric

+0

Tôi có một hệ thống với WebInterface & WebService, tất nhiên tôi cần hai xác thực logic, nhưng tôi không muốn sao chép mã ủy quyền ... làm cách nào để bạn giải quyết vấn đề này? –

+1

Nếu bạn không cho phép ở cả hai cấp, thì bạn có thể kiểm soát quyền truy cập khác như thế nào? Bạn có thể muốn xác thực ở tầng UI và xác thực xác thực tại tầng dịch vụ. Sau đó, ủy quyền tại giao diện người dùng và lớp dịch vụ. –