2014-02-10 2 views
0

많은 SO 및 다른 페이지를 검색했지만 비슷한 사례를 찾을 수 없습니다.ASP.NET MVC4 인증 성공이지만 프로젝트 빌드 후 역할이 누락되었습니다.

내 응용 프로그램이 SimpleMembership을 사용 중입니다. 역할 기반 사용자 메뉴가 있으며 대부분의 작업은 [Authorize (Roles = "aaa, bbb")] 특성과 함께 수행됩니다.

응용 프로그램을 빌드하거나 일정 시간 이상 브라우저를 유휴 상태로두면 사용자는 클릭 한 모든 링크에서 로그인 페이지로 리디렉션됩니다. 이상한 것은 로그인 이름이 여전히 표시 될 수 있지만 역할 이름이 첨부되지 않은 것입니다.

사용자는 위와 같은 상황에서 [Authorize] 속성을 사용하여 작업에 액세스 할 수 있습니다. 내가 누락 된 것이 있는지 궁금하거나 인증이 유효한 한 역할 정보를 활성 상태로 유지할 수 있습니까?

public ActionResult Menu() 
    { 
     if (Roles.IsUserInRole("Admin")) 
     { 
      return View("MenuAdmin"); 
     } 
     if (Roles.IsUserInRole("Advising")) 
     { 
      return View("MenuAdvising"); 
     } 
     if (Roles.IsUserInRole("StudentDevelopment")) 
     { 
      return View("MenuStudentDevelopment"); 
     }... 

사용자 정의 _logonPartial이 역할 정보가 긴으로 사용할 수

> @if (Request.IsAuthenticated) { 
    <text> 
     Logged in: @Html.ActionLink(User.Identity.Name, "Manage", "Account", routeValues: null, htmlAttributes: new { @class = "username", title = "Manage" }) as 
     @String.Join(",", Roles.GetRolesForUser(User.Identity.Name)) 
     @using (Html.BeginForm("LogOff", "Account", FormMethod.Post, new { id = "logoutForm" })) { 
      @Html.AntiForgeryToken() 
      <a href="javascript:document.getElementById('logoutForm').submit()">Log off</a> 
     } 
    </text> 

답변

1

로그인 이름과 역할을 표시합니다 : 여기

는 컨트롤러 액션의 코드 메뉴를 렌더링하는 것입니다 귀하의 경우 귀하는 다음 번호로 전화를 걸고 있습니다 :

Roles.GetRolesForUser(User.Identity.Name) 

역할 목록을 가져옵니다. 이것은 실제로 데이터베이스를 공격하여 역할을 얻습니다. 따라서 사용자 이름이 Identity에서 사용 가능할 때까지 사용자에게 역할이 할당되었다고 가정하면 역할을 반환합니다. 사용자 ID가 인증되면 사용자 이름을 사용할 수 있어야합니다. Request.IsAuthenticated를 확인하고 있습니다. 아마도 User.Identity.IsAuthenticated를 확인하는 것이 좋습니다.

클레임을 사용하여 데이터베이스에 쿼리하지 않고도 역할을 얻을 수있는 방법이 있습니다. 그리고 일반적으로 뷰에 시스템 변수에 대한 논리와 액세스 권한을 부여하지 않습니다. 나는 나의 컨트롤러 액션에서이 접근법을 사용하여 역할을 얻는다.

 var prinicpal = (ClaimsPrincipal)Thread.CurrentPrincipal; 
     var roles = prinicpal.Claims.Where(c => c.Type == ClaimTypes.Role).Select(c => c.Value); 
     ViewBag.Roles = roles; 

중 하나는 당신이 (가) ViewBag에 조회에 필요하거나보기에 전달되는 모델을 생성 정보를 넣어. 역할을 얻는이 접근 방식은 데이터베이스로 왕복 할 필요가 없습니다.

업데이트 MVC 4에 대한 표준 AuthorizeAttribute는 역할을 얻기 위해 (귀하의 경우 SimpleMembership에) 구성된 회원 및 역할 공급자를 사용하여 댓글

를 해결하기 위해. 클레임이 사용 된 곳을 주장하지 않고 매번 데이터베이스로 이동합니다. 실제로 데이터베이스에 두 번 가야합니다. 한 번 로그인 한 사용자의 사용자 ID를 얻은 다음 해당 사용자 ID를 기반으로 역할을 얻으십시오. 별로 효율적이지 않습니다. 놀랍게도 사용자가 역할에 대해 매개 변수로 전달하지 않아도 사용자가 역할에 대해 권한을 부여 할 필요가 없으며 인증 만하면됩니다. 프로파일 러를 사용하여이를 확인했습니다.

데이터베이스를 더 효율적으로 만들고 필요 없게하려면 사용자 지정 AuthorizeAttribute를 작성하여 대신 클레임을 사용할 수 있습니다. Here is an article that describes how to do this, 예제 소스 코드 링크.

빌드 직후에 발생하는 설명하는 시나리오를 설명 할 수 없습니다.그러나 사용자 지정 특성을 만들어 대신 사용하면 디버깅하고 정확히 무엇이 진행되고 있는지 볼 수 있습니다. 또한 프로덕션 환경에서 볼 수있는 일반적인 시나리오가 아니 어서 걱정하지 않으셔도됩니다.

+0

답변 해 주셔서 감사합니다. 상황은 : 각 빌드 후에 사용자가'[Authorize (Roles = "XXX, BBB")]'액션에 액세스 할 때 로그인 페이지로 리디렉션됩니다. '[Authorize]'액션에서는 발생하지 않습니다 (사용자는 빌드 후에 액세스 할 수 있습니다). 내 관찰에서 사용자는 빌드 후에도 로그인되지만 역할은 누락됩니다. 데이터베이스 연결 시간 초과 문제입니까? action 속성을 실행할 때 역할을 유지할 수있는 방법이 있는지 궁금합니다. 감사합니다 – horizon1711

+0

내 업데이트 된 답변을 참조하십시오. –

+0

역할을 상실한 유휴 상태를 시뮬레이트하기위한 응용 프로그램을 만들려고했습니다. 이제는 "역할의 상실이지만 인증 된"IIS 응용 프로그램 풀의 유휴 시간 제한이 해결되었습니다. 연장 된 시간 초과 및 잘 작동합니다. 당신의 도움을 주셔서 감사합니다. – horizon1711