문제

이 코드에서 내가 본 문제는 이 코드가 많이 재사용된다는 것입니다.인증된 사용자(사이트 관리자 제외)가 편집/생성하는 모든 항목은 해당 "스튜디오" 개체에만 액세스할 수 있습니다.

여러분 모두에게 제 질문이 있습니다.서비스 계층을 클라이언트의 지식에서 추상화할 수 있도록 이를 어떻게 리팩토링하시겠습니까?나중에 독립형 데스크탑 애플리케이션에서 서비스 계층을 재사용할 계획입니다.

저의 잘못된 방식을 좀 밝혀주세요!정말 감사드립니다.

AuthorizeOwnerAttribute.cs (Authorize속성)

protected override bool AuthorizeCore(HttpContextBase httpContext)
{
    // Get the authentication cookie
    string cookieName = FormsAuthentication.FormsCookieName;
    HttpCookie authCookie = httpContext.Request.Cookies[cookieName];

    // If the cookie can't be found, don't issue the ticket
    if (authCookie == null) return false;

    // Get the authentication ticket and rebuild the principal & identity
    FormsAuthenticationTicket authTicket = FormsAuthentication.Decrypt(authCookie.Value);
    string[] userData = authTicket.UserData.Split(new[] { '|' });

    int userId = Int32.Parse(userData[0]);
    int studioID = Int32.Parse(userData[1]);
    GenericIdentity userIdentity = new GenericIdentity(authTicket.Name);
    WebPrincipal userPrincipal = new WebPrincipal(userIdentity, userId, studioID);
    httpContext.User = userPrincipal;

    return true;
}

내 "사용자" 컨트롤러 내부에서 이 특성을 소유자가 필요한 모든 메서드에 연결합니다.

    [AuthorizeOwner]
    public ActionResult Edit(int Id)
    {
        IUser user = userService.GetById(HttpContext.User, Id);
        return View(user);
    }

이제 내 서비스 계층에서는 요청된 개체에 대한 액세스 권한이 있는지 전달된 IPrincipal을 확인하는 곳입니다. 냄새가 나는 곳은 다음과 같습니다.

UserService.cs

    public IUser GetById(IPrincipal authUser, int id)
    {
        if (authUser == null) throw new ArgumentException("user");

        WebPrincipal webPrincipal = authUser as WebPrincipal;
        if (webPrincipal == null) throw new AuthenticationException("User is not logged in");

        IUser user = repository.GetByID(id).FirstOrDefault();
        if (user != null)
        {
            if (user.StudioID != webPrincipal.StudioID) throw new AuthenticationException("User does not have ownership of this object");
            return user;
        }

        throw new ArgumentException("Couldn't find a user by the id specified", "id");
    }
도움이 되었습니까?

해결책

실제 ID를 쿠키에 저장할지는 잘 모르겠습니다. 노출이 너무 심해서요.나는 세션 해시를 사용하여 해당 데이터를 저장하여 노출되지 않고 서버에 유지하는 경향이 있습니다.

또한 (userID를 전달하여) 모델을 사용하여 반환할 개체를 결정합니다.일치하는 studioID가 있는 것입니다.이렇게 하면 컨트롤러가 "GetObjects(int id)"만 호출하면 됩니다. 컨트롤러가 아무것도 액세스할 수 없으면 null 또는 빈 컬렉션을 다시 얻게 됩니다.나에게는 그게 더 깨끗하다고 ​​느껴져요.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top