2011-09-01 3 views
0

내 MVC 응용 프로그램은 관리자와 일반 사용자로 구성됩니다. 관리자는 시스템을 사용하여 다른 고객으로 등록 할 수 있으며 사용자를 시스템에 추가 할 수 있습니다.Mvc 앱에서 Json 요청을 보호하는 가장 좋은 방법은 무엇입니까?

컨트롤러는 이미 특정 페이지에 대한 무단 액세스를 방지하기 위해 특정 컨트롤러에 권한 필터를 가지고 있습니다.

그러나 관리자 권한으로 로그인 한 사용자가 Json 게시물을 검사하지 못하도록하거나 자바 스크립트에서 가져 와서 직접 볼 수있는 특정 데이터의 ID로 'get'을 호출한다고합시다. 예 :/사용자/1

내 응용 프로그램을 테스트하면 AJAX get을 게시하여 현재 인증 된 사용자의 관리하에 있지 않은 시스템의 다른 사용자의 세부 정보를 검색 할 수 있습니다.

사용자가 데이터를 볼 수 있는지 확인하기 위해 서비스 메소드가 호출 될 때마다 액세스 확인 메소드를 작성할 수 있습니다. 장소 전체에서 액세스 확인 방법으로 응용 프로그램을 처리하지 않고이 문제를 해결할 수있는 좋은 방법입니까?

현재 구현

public class PeopleController : ApplicationController 
{ 
    public ActionResult GetMemberDetails(int memberId) 
    {    
     var member = _peopleService.GetMemberById(memberId); 
     return Json(member, JsonRequestBehavior.AllowGet); 
    } 
} 

public class PeopleService : IPeopleService 
{ 
    public MemberModel GetMemberById(int memberId) 
    { 
     // Void function which throws Unauthorised exception 
     MemberAccessCheck(memberId); 

     var member = Mapper.Map<Member, MemberModel>(_memberRepository.GetById(memberId)); 
     return member; 
    } 
} 

내 서비스에서 MemberAccessCheck 기능을 여러 번 호출합니다.

답변

1

이 체크는 컨트롤러 또는 서비스 내에 작성해야합니다. 기본적으로 서비스 계층 관점에서 데이터를 필터링하기 때문에이 동작에 사용자 지정 특성 필터를 사용해야한다고 생각하지 않습니다. Auhorize 속성도이 취지에 적합하지 않습니다.

내가 제안하는 것은 컨트롤러에서 현재 userId를 받아들이는 서비스 메서드 (User.Identity 가져 오기)를 서비스에 보내 사용자가 보거나 변경할 수있는 사용자 또는 단일 사용자의 목록을 가져 오는 것입니다 . 따라서 액세스 확인이 반드시 필요하지는 않지만 서비스가 작동하는 방식 (비즈니스 규칙)이 될 것입니다.

서비스 방법의 예 :

User GetAdminUser(int userId, int adminId); 
List<User> GetAdminUsers(int adminId); 

아니면, 그냥 이전 서비스

User GetUser(int userId); 
User GetUser(int userId, int adminId); 
+0

그럼 Json 요청에서 ID를 수락하는 모든 방법에서 액세스 검사가 필요합니까? – jaffa

+0

@jaffa, 컨트롤러에 예제와 예제 제공 –

+0

컨트롤러가 아닌 요청 된 ID의 서비스 레이어를 확인했습니다. 이게 최선의 관행인가? – jaffa

1

당신은 지역에서 관리자의 모든 기능을 배치 고려해야 과부하. 그렇게하면 지역 루트를 사용하여 RouteConstraint을 구현할 수 있습니다. 이는 AJAX 요청에 제출 된 ID를 검사하여 요청한 사용자 범위 내에있는 ID를 확인할 수 있습니다. 이 지역에 대한 AreaRegistration.cs 파일에있는 당신의 가상 경로는 다음과 같습니다

public override void RegisterArea(AreaRegistrationContext context) 
{ 
    context.MapRoute(
     "Admin_default", 
     "Admin/{controller}/{action}/{id}", 
     new { controller = "Home", action = "Index", id = UrlParameter.Optional }, 
     new { id = new IsActionAuthorized() } 
    ); 
} 

이 그런 다음 RouteConstraint는 다음과 같이 보일 것입니다 :

public class IsActionAuthorized : IRouteConstraint 
{ 
    public IsActionAuthorized() 
    { } 

    private MyEntities _db = new MyEntities(); 

    public bool Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection) 
    { 
     // return true if no id was submitted 
     if (String.IsNullOrEmpty(values[parameterName])) 
      return true; 

     // return true if action is authorized 
     var requestId = Convert.ToInt32(values[parameterName]); 
     var authorized = false; 

     // code to check against requester's id, to determine 
     // if requestedId is within requester's authority 
     // set authorized to true only if the request is authorized for this requester 

     return authorized; 
    } 
} 

이 당신에게 단일 진입 점을 제공, 여기서 필요한 게이트 키핑 테스트를 수행 할 수 있습니다. 테스트가 실패하면 요청은 라우팅에 실패하고 404 오류를 반환합니다. 그러나

0

/json으로 게시물을 검사 에서 그들을 방지 얻는 자바 스크립트와 수동으로 특정 데이터의 ID가 '수'는 볼 수 를 호출하는 것, 내가 관리 사용자가 로그인이 있다고? 예 :/ 사용자/1

아무 것도 없습니다.

이러한 요청에 HTTPS를 사용할 수 있으므로 적어도 데이터는 암호화됩니다.

서비스 방법이 일 때마다 액세스 확인 메소드를 작성하여 사용자가 데이터를 볼 수 있는지 확인합니다.

아마도이 작업을 수행해야합니다. 웹 응용 프로그램에서는 사용자에게 오는 요청이 유효하다는 것을 믿을 수 없습니다.

이 코드는 매우 특수한 경향이 있으므로 사용자를 대신하여 처리하는 "프레임 워크"가 많지 않습니다. 최선의 방법은 필요한 모든 곳에서 쉽게 응용 프로그램에 연결할 수있는 방식으로이 코드를 작성하는 것입니다.

관련 문제