2017-10-11 1 views
5

우리는 여러 가지 양식이있는 페이지가 있습니다. 각 광고에는 @Html.AntiForgeryToken()이 있습니다. 내 로컬 컴퓨터에서 모든 것이 훌륭합니다.__RequestVerificationToken이 항상 생성되지는 않습니다.

Azure (PAAS)에 배포했지만 모든 요청에 ​​ 일 때 __RequestVerificationToken이 생성되지 않았습니다. 언젠가는 거기에 있고 언젠가는 내가 얻을 필요한 위조 방지 쿠키가 존재하지 않습니다 그리고 드물게 토큰이과 일치하지 않습니다.

나는이 시점에서 완전히 단서가 없다. 우리 코드 나 Azure 환경에 잘못된 것이 있는지 알아낼 수 없습니까? 이 양식에는 아약스가 없습니다.

우리는 <machineKey> 섹션을 web.config에 추가했습니다. 캐싱 없음. 새 장치에서 처음부터 발생하는 경우도 있습니다.

+0

혹시이 답변을 찾았습니까? –

+0

아니요, 우리는 위조 방지 검사를 제거해야했습니다 (간단한 통합 양식에 사용되었습니다. Azure 설치에는 두 개의 논리적 CD가 있었기 때문에 요청 및 응답을 처리하는 다른 CD와 관련이 있습니다. 그건 내 추측이야. – TamerM

+0

슬픈 일이지만, 나는 당신이 폼 액션에 정의 된 도메인을 가지고 있지 않으면 (POST를 위해 사용자를 다른 CD로 리디렉션하지 않으면 문제가 될 것이라고 생각하지 않지만, UrlHelper를 사용하면 도메인간에 사용자를 리디렉션하지 않으므로이 경우가 해당됩니다. –

답변

1

귀하의 문제는 한 페이지에 여러 위조 방지 토큰이있는 여러 양식이 있다고 생각됩니다. 페이지 요청시 양식 숨김 필드에는 두 개의 다른 토큰이 있지만 쿠키에는 하나의 토큰 만 있습니다. 양식 POST에 오류가 발생하는 일치하지 않는 토큰이 있습니다.

페이지에 하나의 양식 만 있으면 AFT가 어떻게 작동하는지보십시오. 그것이 정상적으로 작동한다면 내 가정은 정확합니다.

This answer에는 여러 양식의 페이지에 대한 가능한 해결 방법이 포함되어 있지만 here과 같은 몇 가지 보안 단점이 있습니다.

로컬 호스트에서 모든 것이 정상적으로 작동하는지 잘 모르겠습니다. 간단한 응용 프로그램을 만들고 올바른 쿠키 토큰을 사용하여 양식 POST를 시도했지만 이전 세션의 이전 양식 토큰을 시도했습니다. 놀랍게도 그러한 POST는 성공적으로 통과합니다. asp.net에는이 경우 로컬 요청에 대한 특별한 처리가있을 수 있습니다. 이것에 대한 정보를 찾지 못했습니다.

내 대답은 여전히 ​​당신은 추가 분석을 위해 다음과 같은 데이터를 제공하십시오 수 있습니다 도움이되지 않는 경우 : 반환 된 HTTP 헤더를

  1. 원본 페이지 요청을하고 위조 방지 토큰을 형성한다.
  2. 전송 된 HTTP 헤더로 POST 요청을 보냅니다.
+0

OP의 게시물에 따르면 토큰이 일치하지 않는 경우 (여러 개의 토큰이있는 경우 btw) 문제가 항상 존재하지는 않습니다. 또한 ASP.NET은 비교하기 전에 위조 방지 토큰을 해독합니다. 두 가지 토큰이 모두 쿠키에 해당하는 데이터를 포함하는 경우 양식에 두 가지 토큰이 있는지 여부는 중요하지 않습니다. 또한 내 시스템에서 여러 양식과 양식 토큰이 문제가 아니라는 것을 알았습니다. 문제는 브라우저에서 전혀 쿠키를 보내지 않았기 때문입니다. –

+0

사실, 토큰은 바이너리 버퍼로만 비교되는 것이 아니라 내부에서 유지되는 보안 토큰에 의해 해독되고 비교됩니다. 위조 토큰 내부 정보에 대한 좋은 기사 : https://www.codeproject.com/Articles/793384/ASP-NET-Anti-Forgery-Tokens-internals. OP는 때로는 '토큰이 오류와 일치하지 않습니다'라는 말을 들었 기 때문에 제 가정은 여전히 ​​문제가 될 수 있습니다. 그렇지 않다면, 내 대답의 맨 아래에 요청한 정보는 적어도 그것이 로컬 클라이언트 또는 원격 서버의 문제인지 여부를 분명히해야합니다. – CodeFuller

0

는 센트리와 푸른 웹 서버 로그의 조합을 사용하여, 조사에 상당한 시간을 소비 한 후, 나는 언급 한 오류의 두 주요 원인을 발견했습니다

휴대 전화에

1),시 브라우저가 백그라운드에서 실행 중이면 OS가 갑자기 중지되어 자원을 비울 수 있습니다. 이 경우 일반적으로 페이지는 휴대 전화의 드라이브에 저장되고 브라우저가 다시 열리면 다시로드됩니다.

하지만 이번에는 세션 쿠키 인 위조 토큰이 본질적으로 새로운 세션이므로 이미 만료되었습니다. 따라서 이전 세션의 HTML을 사용하여 위조 방지 쿠키없이 페이지가로드됩니다. 이로 인해 The required anti-forgery cookie is not present 예외가 발생합니다.

2) 겉보기와 관련되어 있지만, tokens do not match 예외는 일반적으로 접선으로 만 관련됩니다. 원인은 동시에 여러 탭을 여는 사용자 행동 인 것 같습니다.

위조 방지 쿠키는 사용자가 양식이있는 페이지에 도착한 경우에만 할당됩니다. 이것은 그들이 당신의 홈페이지에 갈 수 있고 위조 방지 쿠키가 없다는 것을 의미합니다. 그런 다음 마우스 가운데 버튼을 사용하여 여러 개의 탭을 열 수 있습니다. 여러 탭은 여러 개의 병렬 요청으로, 위조 방지 쿠키가 없습니다.

이러한 요청에는 위조 방지 쿠키가 없으므로 각각에 대해 ASP.NET은 쿠키에 대해 별도의 의사 랜덤 토큰을 생성하고이를 양식에 사용합니다. 그러나 수신 된 마지막 헤더의 결과 만 유지됩니다. 이는 위조 방지 쿠키가 무시 되었기 때문에 다른 모든 페이지의 페이지에 유효하지 않은 토큰이 있음을 의미합니다.

솔루션을

, 나는 페이지가 어떤 형태가없는 경우에도,

  1. 안티 위조 쿠키가 모든 페이지에 할당되어 있는지 확인해야 글로벌 필터 및
  2. 안티를 만들었습니다 -Fortery 쿠키는 세션에 바인드되지 않습니다. 수명은 사용자 로그인 토큰과 일치하도록 조정해야하지만 모바일 장치가 세션없이 페이지를 다시로드하는 경우 세션간에 지속되어야합니다.

아래 코드는 내부에 전역 필터로 추가해야하는 FilterAttribute입니다. 보안 구멍이 생길 것이라고 생각하지 않지만 보안 전문가가 아니므로 모든 의견을 환영합니다.

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)] 
public class AntiForgeryFilter : FilterAttribute, IActionFilter 
{ 
    public void OnActionExecuting(ActionExecutingContext filterContext) 
    { 
     var cookie = filterContext.HttpContext.Request.Cookies.Get(AntiForgeryConfig.CookieName); 
     var addCookie = true; 
     if (string.IsNullOrEmpty(cookie?.Value)) 
     { 
      cookie = filterContext.HttpContext.Response.Cookies.Get(AntiForgeryConfig.CookieName); 
      addCookie = false; 
     } 
     if (string.IsNullOrEmpty(cookie?.Value)) 
     { 
      AntiForgery.GetTokens(null, out string cookieToken, out string _); 
      cookie = new HttpCookie(AntiForgeryConfig.CookieName, cookieToken) 
      { 
       HttpOnly = true, 
       Secure = AntiForgeryConfig.RequireSsl 
      }; 
     } 
     cookie.Expires = DateTime.UtcNow.AddYears(1); 
     if(addCookie) filterContext.HttpContext.Response.Cookies.Add(cookie); 
    } 

    public void OnActionExecuted(ActionExecutedContext filterContext) 
    { 
    } 
} 
관련 문제