단일 페이지 응용 프로그램을 작성하고 위조 방지 토큰에 문제가 있습니다.
문제가 발생하는 이유를 알고 있으며 문제를 해결하는 방법을 모르겠습니다.
다음과 같은 경우 오류가 발생합니다.
- 로그인하지 않은 사용자는 대화 상자를 생성합니다 (위조 방지 토큰 생성).
- 사용자가 대화 상자를 닫습니다.
- 사용자 로그인
- 사용자는 같은 대화 상자를 엽니 다
- 사용자가 대화 상자에서 양식을 제출
위변조 방지 토큰은 “”사용자를위한 것이지만 현재 사용자는 “username”입니다.
내 응용 프로그램이 100 % 단일 페이지이며, 사용자가 성공적으로 아약스 게시물을 통해 로그인 할 때 때문에 이런 일이 발생하는 이유는 /Account/JsonLogin
, 단순히 서버에서 반환 된 “인증 된 뷰”로 현재보기를 전환하지만 를 다시로드하지 않습니다 페이지.
3 단계와 4 단계 사이에 페이지를 간단히 다시로드하면 오류가 없기 때문에 이것이 이유라는 것을 알고 있습니다.
따라서 @Html.AntiForgeryToken()
로드 된 양식에서 페이지를 다시로드 할 때까지 여전히 이전 사용자의 토큰을 반환하는 것으로 보입니다 .
@Html.AntiForgeryToken()
인증 된 새로운 사용자에 대한 토큰을 반환하도록 변경 하려면 어떻게 해야합니까?
호출 할 때 마다 GenericalPrincipal
사용자 정의 IIdentity
에 새 항목 을 삽입합니다 . 실제로 속성이 true로 설정된 사용자 정의 ID 는 페이지를 다시로드하지 않으면 여전히 이전 사용자에 대한 토큰을 렌더링하는 것 같습니다.Application_AuthenticateRequest
@Html.AntiForgeryToken()
HttpContext.Current.User.Identity
IsAuthenticated
@Html.AntiForgeryToken
답변
위조 방지 토큰은 더 나은 유효성 검사를 위해 사용자의 사용자 이름을 암호화 된 토큰의 일부로 포함하기 때문에 발생합니다. 처음 호출 할 @Html.AntiForgeryToken()
때 사용자가 로그인하지 않았으므로 토큰에 사용자 이름에 대한 빈 문자열이 표시됩니다. 사용자가 로그인 한 후 위조 방지 토큰을 바꾸지 않으면 초기 토큰이 사용 되었기 때문에 유효성 검사를 통과하지 못합니다. 익명의 사용자이며 이제 사용자 이름이 알려진 인증 된 사용자가 있습니다.
이 문제를 해결하기위한 몇 가지 옵션이 있습니다.
-
이번에는 SPA가 전체 POST를 수행하도록하고 페이지가 다시로드 될 때 업데이트 된 사용자 이름이 포함 된 위조 방지 토큰을 갖게됩니다.
-
@Html.AntiForgeryToken()
로그인 한 직후에 부분적으로 확인하고 다른 AJAX 요청을 수행하고 기존 위조 방지 토큰을 요청의 응답으로 바꿉니다. -
위조 방지 유효성 검사가 수행하는 신원 확인을 비활성화하십시오. Application_Start 메소드에 다음을 추가하십시오
AntiForgeryConfig.SuppressIdentityHeuristicChecks = true
..
답변
오류를 해결하려면 다음과 같이 로그인 정보 페이지 OutputCache
에 데이터 주석 을 배치해야합니다 ActionResult
.
[OutputCache(NoStore=true, Duration = 0, VaryByParam= "None")]
public ActionResult Login(string returnUrl)
답변
내 응용 프로그램에서 여러 번 발생하므로 Google에서 사용하기로 결정했습니다!
이 오류에 대한 간단한 설명을 찾았습니다! 사용자가 로그인 버튼을 두 번 클릭하고 있습니다! 다른 사용자가 아래 링크에서 그것에 대해 이야기하는 것을 볼 수 있습니다.
위조 방지 토큰을 제공 한 MVC 4는 사용자 “”을위한 것이지만 현재 사용자는 “user”입니다.
도움이 되길 바랍니다! =)
답변
나는 같은 문제가 있었고,이 더러운 해킹은 적어도 더 깨끗한 방식으로 고칠 수있을 때까지 해결되었습니다.
public ActionResult Login(string returnUrl)
{
if (AuthenticationManager.User.Identity.IsAuthenticated)
{
AuthenticationManager.SignOut();
return RedirectToAction("Login");
}
…
답변
이미 인증 된 상태에서 로그인하면 메시지가 나타납니다.
이 도우미는 [ValidateAntiForgeryToken]
속성 과 정확히 동일한 기능을 수행 합니다.
System.Web.Helpers.AntiForgery.Validate()
[ValidateAntiForgeryToken]
컨트롤러 에서 속성을 제거 하고이 헬퍼를 조치 방법에 배치하십시오.
따라서 사용자가 이미 인증 된 경우 홈 페이지로 리디렉션하거나이 확인 후 유효한 위조 방지 토큰 확인을 계속하지 않으면
if (User.Identity.IsAuthenticated)
{
return RedirectToAction("Index", "Home");
}
System.Web.Helpers.AntiForgery.Validate();
오류를 재현하려면 다음과 같이 진행하십시오. 로그인 페이지에 있고 인증되지 않은 경우. 탭을 복제하고 두 번째 탭으로 로그인 한 경우 그리고 로그인 페이지의 첫 번째 탭으로 돌아와서 페이지를 다시로드하지 않고 로그인하려고하면 …이 오류가 발생합니다.
답변
프로덕션 서버에서 거의 동일한 예외가 발생합니다.
왜 그런가요?
유효한 자격 증명을 사용하여 사용자 로그인 한 후 한 번 로그인하여 다른 페이지로 리디렉션하면 뒤로 버튼을 누르면 로그인 페이지가 표시되고이 예외가 발생할 때 유효한 자격 증명을 다시 입력했습니다.
해결하는 방법?
이 줄을 추가하고 완벽하게 작동하면 오류가 발생하지 않습니다.
[OutputCache(NoStore = true, Duration = 0, VaryByParam = "None")]
답변
등록 과정에서 상당히 구체적이지만 비슷한 문제가있었습니다. 사용자가 이메일 링크를 클릭하면 로그인되어 계정 정보 화면으로 바로 전송되어 추가 정보를 채 웁니다. 내 코드는 다음과 같습니다
Dim result = Await UserManager.ConfirmEmailAsync(userId, code)
If result.Succeeded Then
Dim appUser = Await UserManager.FindByIdAsync(userId)
If appUser IsNot Nothing Then
Dim signInStatus = Await SignInManager.PasswordSignInAsync(appUser.Email, password, True, shouldLockout:=False)
If signInStatus = SignInStatus.Success Then
Dim identity = Await UserManager.CreateIdentityAsync(appUser, DefaultAuthenticationTypes.ApplicationCookie)
AuthenticationManager.SignIn(New AuthenticationProperties With {.IsPersistent = True}, identity)
Return View("AccountDetails")
End If
End If
End If
Return View ( “AccountDetails”)가 토큰 예외를 제공한다는 것을 알았습니다. ConfirmEmail 함수는 AllowAnonymous로 장식되었지만 AccountDetails 함수에는 ValidateAntiForgeryToken이 있었기 때문에 추측하고 있습니다.
Return to Return RedirectToAction ( “AccountDetails”)을 변경하면 문제가 해결되었습니다.