로그인 요청 인증 토큰 문제
개발 프로젝트의 오류 로그를 살펴본 결과 다음과 같은 오류가 발견되었습니다 ( 무고한
유죄
를 보호하기 위해 이름이 변경되었습니다
)-
제공된 위조 방지 토큰은 ""사용자를위한 것이지만 현재 사용자는 "admin"입니다.
이것은 재현하기가 특별히 어려운 문제가 아닙니다.
- 로그인 페이지에서 애플리케이션을 엽니 다.
- 에 두 번째 창 또는 탭을 열고 같은 브라우저 상의 동일한 컴퓨터 에 로그인하기 전에 로그인 페이지를
- 첫 번째 창에서 로그인 (또는 실제로 두 번째 창에서 순서는 중요하지 않음)
- 나머지 로그인 창에서 로그인 시도
스택 추적은 다음과 같습니다.
System.Web.Mvc.HttpAntiForgeryException (0x80004005) : 제공된 위조 방지 토큰은 ""사용자를위한 것이지만 현재 사용자는 "admin"입니다. System.Web.Helpers.AntiXsrf.TokenValidator.ValidateTokens (HttpContextBase httpContext, IIdentity identity, AntiForgeryToken sessionToken, AntiForgeryToken fieldToken) at System.Web.Helpers.AntiXsrf.AntiForgeryWorker.AntiForgeryWorker.Validate (HttpContextBase httpContext) at System.Web.Helpers. System.Web.Mvc.ValidateAntiForgeryTokenAttribute.OnAuthorization (AuthorizationContext filterContext)의 System.Web.Mvc.ControllerActionInvoker.InvokeAuthorizationFilters (ControllerContext controllerContext, IList`1 filters, ActionDescriptor actionDescriptor)의 Validate () at System.Web.Mvc.Async.AsyncControllerActionInvoker. <> c__DisplayClass25.b__1e (AsyncCallback asyncCallback, 객체 asyncState)
로그인 방법 서명은 다음과 같습니다.
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public ActionResult Login(LoginModel model, string returnUrl)
{
...
}
이것은 인터넷 "ASP.NET MVC 4 웹 응용 프로그램"템플릿 프로젝트의 메서드에 대한 서명과 정확히 동일합니다. 이는 Microsoft가 ValidateAntiForgeryToken이 필요 / 모범 사례라고 생각했거나 사용 되었기 때문에 여기에 속성을 추가했음을 나타냅니다. 그 밖의 모든 곳.
분명히이 메서드 내 에서 문제를 처리하기 위해 할 수있는 일은 없습니다. ValidateAntiForgeryToken은 사전 요청 필터이며 컨트롤러에 도달하기 전에 요청을 차단하고 있습니다.
양식을 제출하기 전에 사용자가 Ajax를 통해 인증되었는지 확인하고 리디렉션을 시도하거나 속성을 제거 할 수 있습니다.
질문은 이것이다-사용자 가 이미 귀하의 사이트에 대해 인증을 받았을 때 토큰이 다른 사이트 (CSRF)로부터의 요청을 방지하기위한 것임을 이해합니다. 따라서 정의에 따라 사용할 양식에서 토큰 을 제거하는 것이 문제입니다. 인증되지 않은 사용자가 ?
아마도이 인스턴스의 속성은 응용 프로그램에 대한 가짜 로그인 양식을 제공하는 악의적 인 행위자를 완화하도록 설계되었을 것입니다 (예외가 발생했을 때 사용자가 이미 기록 된 세부 정보를 입력했지만 경고 할 수 있음). 잘못되었습니다). 그렇지 않으면 외부 사이트에서 잘못된 자격 증명을 양식에 제출하면 사이트 자체와 똑같은 결과가 확실히 발생합니까? 잠재적으로 안전하지 않은 입력을 정리하기 위해 클라이언트 유효성 검사 / 위생에 의존하지 않습니다.
다른 개발자가이 문제를 접했거나 (또는 비정상적으로 창의적인 사용자가 있는가) 그렇다면 어떻게 해결 / 완화 했습니까?
업데이트 : 이 문제는 전적으로 의도적으로 MVC5에 여전히 존재하며 "제공된 위조 방지 토큰은 현재 사용자와 다른 클레임 기반 사용자를위한 것입니다."라는 오류 메시지가 표시됩니다. 기본 템플릿 및 ID 공급자를 사용할 때. Microsoft Developer Evangelist와 Troy의 동료 PluralSight 저자 Adam Tuliper ( 로그인 페이지에서 간단히 토큰 제거를 권장하는 위조 방지 토큰 )의 관련 질문과 흥미로운 답변이 있습니다 .
동일한 결과로 ASafaWeb 에서이 패턴을 테스트했습니다 (동일한 기본 구현을 사용함). 내가 생각하는 일은 다음과 같습니다.
- 두 로그인 양식 모두 동일한 __RequestVerificationToken 쿠키 (동일한 DOM에 설정된 동일한 쿠키) 및 동일한 __RequestVerificationToken 숨겨진 필드로로드됩니다. 이러한 토큰은 익명 사용자에게 입력됩니다.
- 로그인 양식 A는 위의 토큰을 사용하여 게시하고 유효성을 검사 한 다음 브라우저 DOM에있는 인증 쿠키를 반환합니다.
- 폼 B 게시물을 로그인 또한 위의 토큰하지만 지금은 로그인 폼 A로부터 인증 쿠키 세트를 올리기도합니다.
문제는 토큰이 익명 사용자에게 입력되었지만 인증 된 사용자의 요청에 전달되기 때문에 3 단계에서 유효성을 검사하지 않는다는 것입니다. 이것이 오류가 표시되는 이유입니다 . 제공된 위조 방지 토큰은 ""사용자를위한 것이지만 현재 사용자는 "admin"입니다.
양식 A가 게시되기 전에 양식 B가로드되었으므로 양식 B는 익명 사용자가 게시 할 것으로 예상되기 때문에이 문제가 발생합니다.
인증되지 않은 사용자가 정의에 따라 사용할 양식에서 제거하는 것이 문제입니까?
위조 방지 토큰이 보호하는 주된 기본 위험은 CSRF 로, 브라우저가 속일 수있는 모든 요청이 자동으로 인증 쿠키를 수반하므로 해당 사용자에서 작업이 수행되기 때문에 일반적 으로 인증 된 사용자를 활용합니다. 대신. 일반적으로 사용자가 인증되지 않았고 여기에서 가장 나쁜 CSRF 사례는 로그인이 위조 된 후 실패하기 때문에 로그인 양식에 존재하지 않습니다. 사용자를 대신하여 정확히 송금하는 것이 아닙니다!
There are other advantages to the anti-forgery token though: for example it prevents brute force attacks actually executing the method and hitting the DB. You need to decide if you're less worried about this and more worried about the scenario you're encountering in your question. Either that or you need to drop down into the request pipeline somewhere and take action if an auth cookie is already present in the request before the anti-forgery validation occurs.
하지만 솔직히 나는 문제가 무엇인지 잘 모르겠습니다. 이 문제를 재현하려면 사용자는 동시에 여러 로그인 양식을 열고 각각에 연속으로 로그인을 시도해야합니다.이 문제가 실제로 발생해도 걱정할 필요가 있습니까? 그리고 이런 일이 발생했을 때 두 번째 로그인이 사용자 지정 오류 페이지를 반환하는 것이 정말로 중요합니까 (물론 프로덕션에서 수행 할 작업)? IMHO, 기본 동작을 그대로 둡니다.
AntiForgeryToken에 대해 실행되는 유효성 검사 코드는 로그인 한 사용자 자격 증명이 변경되지 않았는지 확인합니다. 이러한 자격 증명도 쿠키에서 암호화됩니다. 즉, 팝업 또는 다른 브라우저 탭에서 로그인하거나 로그 아웃 한 경우 다음 예외와 함께 양식 제출이 실패합니다.
System.Web.Mvc.HttpAntiForgeryException (0x80004005):
The provided anti-forgery token was meant for user "", but the current user is "SomeOne".
You can turn this off by putting AntiForgeryConfig.SuppressIdentityHeuristicChecks = true; in Application_Start method inside Global.asax file.
When a AntiForgeryToken doesn’t validate your website will throw an Exception of type System.Web.Mvc.HttpAntiForgeryException. You can make this a little easier by at least giving the user a more informative page targeted at these exceptions by catching the HttpAntiForgeryException.
private void Application_Error(object sender, EventArgs e)
{
Exception ex = Server.GetLastError();
if (ex is HttpAntiForgeryException)
{
Response.Clear();
Server.ClearError(); //make sure you log the exception first
Response.Redirect("/error/antiforgery", true);
}
}
Okay, please correct me if my assumption is incorrect.
When this exception gets thrown, you would prefer to let the user continue on while also maybe displaying a relevant message/warning? Because when this exception gets thrown, we can already know if the current user is authenticated--we have access to the request.
So, why wouldn't this be acceptable?
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public ActionResult Login(LoginModel model, string returnUrl)
{
...
}
/// <summary>
/// Handle HttpAntiForgeryException and redirect if user is already authenticated
/// </summary>
/// <param name="filterContext"></param>
/// <remarks>
/// See: http://stackoverflow.com/questions/19096723/login-request-validation-token-issue
/// </remarks>
protected override void OnException(ExceptionContext filterContext)
{
base.OnException(filterContext);
var action = filterContext.RequestContext.RouteData.Values["action"] as string;
var controller = filterContext.RequestContext.RouteData.Values["controller"] as string;
if ((filterContext.Exception is HttpAntiForgeryException) &&
action == "Login" &&
controller == "MyController" &&
filterContext.RequestContext.HttpContext.User != null &&
filterContext.RequestContext.HttpContext.User.Identity.IsAuthenticated)
{
LogManager.GetCurrentClassLogger().Warn(
"Handled AntiForgery exception because user is already Authenticated: " +
filterContext.Exception.Message, filterContext.Exception);
filterContext.ExceptionHandled = true;
// redirect/show error/whatever?
filterContext.Result = new RedirectResult("/warning");
}
}
Am I missing something obvious here? I'll remove this answer if it has some implication I'm not seeing.
I had the same issue, I solved it by adding machineKey to system.web>
<machineKey validationKey="your machine key numbers"
decryptionKey="Your description key nuumbers" validation="SHA1" decryption="AES" />
Here's a site that generate unique Machnie Keys http://www.developerfusion.com/tools/generatemachinekey/
Works great, I understand that Anti Forgery may not be needed in a Login page, but if someone is determined to hack you site, it comforting to know that [ValidateAntiForgeryToken] is there to thwart them off.
참고URL : https://stackoverflow.com/questions/19096723/login-request-validation-token-issue
'program tip' 카테고리의 다른 글
이 std :: ref 동작이 논리적입니까? (0) | 2020.11.12 |
---|---|
iPhone 애플리케이션을 AppStore에 업로드하는 단계 (0) | 2020.11.12 |
다중 작업 트레이에서 앱이 중지되면 Android 앱에서 Firebase 알림을받지 못함 (0) | 2020.11.12 |
C ++ 함수에서 정확한 "반환"순간 (0) | 2020.11.12 |
특정 경로의 모든 파일과 디렉토리를 빠르게 가져옵니다. (0) | 2020.11.12 |