ASP.NET_SessionId + OWIN 쿠키는 브라우저로 보내지 않습니다


145

Owin 쿠키 인증 사용에 이상한 문제가 있습니다.

IIS 서버 인증을 시작하면 IE / Firefox 및 Chrome에서 완벽하게 작동합니다.

인증으로 몇 가지 테스트를 시작하고 다른 플랫폼에서 로그인했으며 이상한 오류가 발생했습니다. 산발적으로 Owin 프레임 워크 / IIS는 브라우저에 쿠키를 보내지 않습니다. 코드가 올바르게 실행되는 사용자 이름과 비밀번호를 입력하지만 쿠키가 브라우저에 전혀 전달되지 않습니다. 서버를 다시 시작하면 작동하기 시작하고 어느 시점에서 로그인을 시도하고 다시 쿠키 배달을 중지합니다. 코드를 단계별로 실행하면 아무 작업도 수행되지 않으며 오류가 발생하지 않습니다.

 app.UseCookieAuthentication(new CookieAuthenticationOptions
        {
            AuthenticationMode = AuthenticationMode.Active,
            CookieHttpOnly = true,
            AuthenticationType = "ABC",
            LoginPath = new PathString("/Account/Login"),
            CookiePath = "/",
            CookieName = "ABC",
            Provider = new CookieAuthenticationProvider
               {
                  OnApplyRedirect = ctx =>
                  {
                     if (!IsAjaxRequest(ctx.Request))
                     {
                        ctx.Response.Redirect(ctx.RedirectUri);
                     }
                 }
               }
        });

그리고 내 로그인 절차에는 다음 코드가 있습니다.

IAuthenticationManager authenticationManager = HttpContext.Current.GetOwinContext().Authentication;
                            authenticationManager.SignOut(DefaultAuthenticationTypes.ExternalCookie);

var authentication = HttpContext.Current.GetOwinContext().Authentication;
var identity = new ClaimsIdentity("ABC");
identity.AddClaim(new Claim(ClaimTypes.Name, user.Username));
identity.AddClaim(new Claim(ClaimTypes.NameIdentifier, user.User_ID.ToString()));
identity.AddClaim(new Claim(ClaimTypes.Role, role.myRole.ToString()));
    authentication.AuthenticationResponseGrant =
        new AuthenticationResponseGrant(identity, new AuthenticationProperties()
                                                   {
                                                       IsPersistent = isPersistent
                                                   });

authenticationManager.SignIn(new AuthenticationProperties() {IsPersistent = isPersistent}, identity);

업데이트 1 : 문제의 원인 중 하나는 항목을 세션에 추가하여 문제가 시작되는 것 같습니다. 간단한 것을 추가 Session.Content["ABC"]= 123하면 문제가 발생하는 것 같습니다.

내가 만들 수있는 것은 다음과 같습니다 : 1) (Chrome) 로그인하면 ASP.NET_SessionId + 내 인증 쿠키가 나타납니다. 2) session.contents를 설정하는 페이지로 이동합니다 ... 3) 새 브라우저 (Firefox)를 열고 로그인을 시도하면 ASP.NET_SessionId를받지 않거나 인증 쿠키를 얻지 않습니다 .4) 첫 번째 브라우저 계속 작동하는 ASP.NET_SessionId가 있습니다. 이 쿠키를 제거하는 순간 IP 주소 (10.xxx) 및 localhost에서 작업중 인 다른 모든 브라우저와 동일한 문제가 있습니다.

업데이트 2 :ASPNET_SessionId OWIN으로 인증하기 전에 login_load 페이지 에서 처음으로 강제 생성 합니다.

1) OWIN으로 인증하기 전에 Session.Content로그인 페이지에서 임의의 값을 만들어 ASP.NET_SessionId를 시작합니다 .2) 인증하고 추가 세션을 만듭니다 .3) 다른 브라우저가 작동하는 것 같습니다.

이것은 기괴하다. 나는 이것이 ASP 및 OWIN과 관련이 있다고 생각할 수 있습니다.

업데이트 3- 둘 사이의 이상한 동작.

추가 이상한 동작 식별-Owin 시간 초과 및 ASP 세션이 다릅니다. 내가보고있는 것은 내 Owin 세션이 일부 메커니즘을 통해 ASP 세션보다 오래 지속된다는 것입니다. 그래서 로그인 할 때 : 1.) 쿠키 기반 인증 세션이 있습니다.) 세션 변수를 설정했습니다.

owin 쿠키 세션 변수 이전의 세션 변수 (2) "die"는 강제로 다시 로그인하여 전체 응용 프로그램에서 예기치 않은 동작이 발생합니다. (사람은 로그인했지만 실제로는 로그인하지 않았습니다)

3B 업데이트

약간의 파기 후 페이지에서 "양식"인증 시간 초과 및 세션 시간 초과가 일치해야한다는 의견이있었습니다. 나는 정상적으로 두 가지가 동기화되어 있다고 생각하지만 어떤 이유로 든 두 가지가 동기화되어 있지 않습니다.

대안 요약

1) 인증 전에 항상 세션을 먼저 생성하십시오. 응용 프로그램을 시작할 때 기본적으로 세션 만들기Session["Workaround"] = 0;

2) [실험] 쿠키를 유지하는 경우 OWIN 시간 초과 / 길이가 web.config의 sessionTimeout보다 길어야합니다 (테스트 중).


1
ActionResult 로그인 및 ActionResult ExternalLogin에 세션 호출을 추가하면이 문제가 해결되었음을 확인할 수 있습니다. 나는 오직 하나만 필요하다고 확신하지만 둘 다 제자리에 있습니다.
Scott

감사합니다! ... 외부 로그인에 세션을 추가하면 문제가 해결되었습니다 ... 이것은 부두 마법입니다 ...이 문제를 해결하기 위해 이미 6 시간을 낭비했습니다.
xdev

답변:


159

동일한 문제가 발생하여 OWIN ASP.NET 호스팅 구현의 원인을 추적했습니다. 나는 그것이 버그라고 말할 것입니다.

일부 배경

내 연구 결과는 다음 어셈블리 버전을 기반으로합니다.

  • Microsoft.Owin, 버전 = 2.0.2.0, Culture = neutral, PublicKeyToken = 31bf3856ad364e35
  • Microsoft.Owin.Host.SystemWeb, 버전 = 2.0.2.0, Culture = neutral, PublicKeyToken = 31bf3856ad364e35
  • System.Web, 버전 = 4.0.0.0, 문화 = 중립, PublicKeyToken = b03f5f7f11d50a3a

OWIN은 자체 추상화를 사용하여 응답 쿠키 ( Microsoft.Owin.ResponseCookieCollection )에 대해 작업 합니다. 이 구현은 응답 헤더 컬렉션을 직접 래핑하고 이에 따라 Set-Cookie 헤더를 업데이트합니다 . OWIN ASP.NET 호스트 ( Microsoft.Owin.Host.SystemWeb )는 System.Web.HttpResponse를 감싸고 헤더 컬렉션입니다. 따라서 OWIN을 통해 새로운 쿠키가 생성되면 응답 Set-Cookie 헤더가 직접 변경됩니다.

그러나 ASP.NET은 자체 추상화를 사용하여 응답 쿠키를 처리합니다. 이것은 System.Web.HttpResponse.Cookies 속성 으로 노출 되며 봉인 클래스 System.Web.HttpCookieCollection에 의해 구현됩니다 . 이 구현은 응답 Set-Cookie 헤더를 직접 래핑하지 않지만 일부 최적화 및 소수의 내부 알림을 사용하여 상태가 응답 객체로 변경되었음을 나타냅니다.

그런 다음 HttpCookieCollection 변경 상태가 테스트되고 ( System.Web.HttpResponse.GenerateResponseHeadersForCookies () ) 요청 수명이 늦어 쿠키가 Set-Cookie 헤더 로 직렬화 되는 시점 이 있습니다. 이 컬렉션이 특정 상태 인 경우 전체 Set-Cookie 헤더가 먼저 수집되고 컬렉션에 저장된 쿠키에서 다시 생성됩니다.

ASP.NET 세션 구현은 System.Web.HttpResponse.Cookies 속성을 사용하여 ASP.NET_SessionId 쿠키를 저장합니다. 또한 ASP.NET 세션 상태 모듈 ( System.Web.SessionState.SessionStateModule )에는 기본적으로 s_sessionEverSet이라는 정적 속성을 통해 구현되는 몇 가지 기본 최적화가 있습니다. 애플리케이션에 세션 상태로 무언가를 저장 한 경우이 모듈은 각 요청에 대해 약간 더 많은 작업을 수행합니다.


로그인 문제로 돌아 가기

이 모든 부분을 통해 시나리오를 설명 할 수 있습니다.

사례 1-세션이 설정되지 않았습니다

System.Web.SessionState.SessionStateModule , s_sessionEverSet 특성이 false입니다. 세션 상태 모듈에서 세션 ID를 생성 하지 않으며 System.Web.HttpResponse.Cookies 수집 상태가 변경된 것으로 감지되지 않습니다 . 이 경우 OWIN 쿠키가 브라우저로 올바르게 전송되고 로그인이 작동합니다.

사례 2-세션이 응용 프로그램 어딘가에서 사용되었지만 사용자가 인증을 시도하기 전에는 사용되지 않았습니다.

System.Web.SessionState.SessionStateModule , s_sessionEverSet 특성이 true입니다. 세션 ID는 SessionStateModule 에 의해 생성되고 ASP.NET_SessionId는 System.Web.HttpResponse.Cookies 컬렉션에 추가 되지만 사용자 세션이 실제로 비어 있으면 요청 수명이 나중에 제거됩니다. 이 경우에는 System.Web.HttpResponse.Cookies의 수집 상태 변화로서 검출 하고 설정 쿠키 쿠키 헤더 값 직렬화 헤더 전에 먼저 삭제된다.

이 경우 OWIN 응답 쿠키는 "손실"되고 사용자는 인증되지 않으며 로그인 페이지로 다시 리디렉션됩니다.

사례 3-사용자가 인증을 시도하기 전에 세션이 사용됩니다

System.Web.SessionState.SessionStateModule , s_sessionEverSet 특성이 true입니다. 세션 ID는 SessionStateModule 에 의해 생성되고 ASP.NET_SessionId는 System.Web.HttpResponse.Cookies에 추가됩니다 . System.Web.HttpCookieCollectionSystem.Web.HttpResponse.GenerateResponseHeadersForCookies ()의 내부 최적화로 인해 Set-Cookie 헤더가 먼저 지워지지 않고 업데이트 만됩니다.

이 경우 OWIN 인증 쿠키와 ASP.NET_SessionId 쿠키가 모두 응답으로 전송되고 로그인이 작동합니다.


쿠키와 관련된 일반적인 문제

보다시피이 문제는보다 일반적이며 ASP.NET 세션에만 국한되지 않습니다. Microsoft.Owin.Host.SystemWeb을 통해 OWIN을 호스팅 하고 있고 사용자가 무언가 System.Web.HttpResponse.Cookies 컬렉션을 직접 사용하는 경우 위험에 노출됩니다.

예를 들어이 작동 하고 두 쿠키가 모두 브라우저로 올바르게 전송됩니다 ...

public ActionResult Index()
{
    HttpContext.GetOwinContext()
        .Response.Cookies.Append("OwinCookie", "SomeValue");
    HttpContext.Response.Cookies["ASPCookie"].Value = "SomeValue";

    return View();
}

그러나 이것은 그렇지 않으며 OwinCookie는 "잃어버린"것입니다 ...

public ActionResult Index()
{
    HttpContext.GetOwinContext()
        .Response.Cookies.Append("OwinCookie", "SomeValue");
    HttpContext.Response.Cookies["ASPCookie"].Value = "SomeValue";
    HttpContext.Response.Cookies.Remove("ASPCookie");

    return View();
}

둘 다 VS2013, IISExpress 및 기본 MVC 프로젝트 템플릿에서 테스트되었습니다.


7
테스트 환경에서이 문제를 디버깅하고 해결하기 위해 며칠을 보냈습니다. 내가 찾은 유일한 해결 방법은 제안한 것과 같습니다 (사용자 인증 전에 세션 설정). 나는 katanaproject ... katanaproject.codeplex.com/workitem/197에 문제를보고 했으므로 누군가가 거기에 의견을 말할 것입니다.
Tomas Dolezal

11
이것은 특히 vs2013에 대한 템플릿을 owin으로 패키지했기 때문에 매우 심각한 결함입니다.
Piotr Stulinski

2
이 추가 조사를 원하는 사람을 위해, 나는 github.com/Neilski/IdentityBugDemo에서 테스트 프로젝트 생성 한
Neilski

1
세션을 백업 저장소로 사용하는 Controller.TempData를 사용하기 때문에이 문제가 발생합니다. 이전 요청에 ASP_NET.SessionId 쿠키가없는 경우 로그인 할 수없는 상태를 쉽게 재현 할 수 있습니다.
kingdango

2
드디어! 이것이 이상한 문제입니다. 감사합니다. 이것은이 답변이 작성된 후 2 년 동안 여전히 문제입니다.
Spivonious

43

@TomasDolezal의 훌륭한 분석부터 Owin과 System.Web 소스를 모두 살펴 보았습니다.

문제는 System.Web에 쿠키 정보의 자체 마스터 소스가 있으며 Set-Cookie 헤더가 아니라는 것입니다. Owin은 Set-Cookie 헤더에 대해서만 알고 있습니다. 해결 방법은 Owin에서 설정 한 쿠키가 HttpContext.Current.Response.Cookies컬렉션 에도 설정되어 있는지 확인하는 것 입니다.

쿠키 미들웨어 등록 바로 위에 배치하기 위해 정확하게 수행 하는 작은 미들웨어 ( source , nuget )를 만들었습니다 .

app.UseKentorOwinCookieSaver();

app.UseCookieAuthentication(new CookieAuthenticationOptions());

1
이것을 시도해보십시오. asp.net Identity 2.2.0-alpha1 이후에 로그인 할 때뿐만 아니라 사용자를 로그 아웃 할 때도 문제가 발생하기 시작했습니다. 사용자가 로그인하기 직전에 세션을 설정 한 후 로그인 문제가 해결되었지만 로그 아웃 문제는 지속됩니다. 노력해 주셔서 감사합니다 .. 그런데 설치를 제외하고해야 할 일이 있습니까? 패키지?
wooer

app.UseKentorCookieMiddlewareSaver();Startup.Auth.cs에서 활성화해야합니다 . 로그 아웃 쿠키 지우기도 처리해야합니다.
Anders Abel

Anders Abel에게 감사합니다. 로그인과 로그 아웃 모두 잘 작동합니다. 그러나 위 주석의 코드는 성공하지 않고 변경해야합니다 (성공하지 않았기 때문에 :) . app.UseKentorOwinCookieSaver()패키지의 GitHub 페이지 에서와 같이 원래 답변에 포함될 수 있습니다 .
wooer

1
잘못된 문서를 확인해 주셔서 감사합니다. 실제로 GitHub 페이지에서 이미 수정되었지만 지금도 내 답변에서 업데이트되었습니다.
Anders Abel

@AndersAbel이 github 프로젝트에 대한 Meetup 가입을 추가하려고합니다 : github.com/owin-middleware/OwinOAuthProviders ''. 다른 날에 Asana를 추가했지만 문제가 없었지만 어떤 이유로 Meetup을 사용하면 Account // ExternalLoginCallback의 await AuthenticationManager.GetExternalLoginInfoAsync () 메서드가 null을 반환합니다. 불행히도 NuGet 패키지로 문제가 해결되지 않았습니다. 문제를 더 잘 해결하고 프로젝트를 추진할 수 있기 때문에 나와 함께 검토 할 시간이 있는지 궁금합니다.
Anthony Ruffino

42

간단히 말해 .NET 쿠키 관리자는 OWIN 쿠키 관리자를 극복하고 OWIN 레이어에 설정된 쿠키를 덮어 씁니다 . 해결 방법은 Katana Project here의 솔루션으로 제공되는 SystemWebCookieManager 클래스 를 사용하는 입니다. 이 클래스 또는 이와 유사한 클래스 를 사용해야합니다. OWIN이 .NET 쿠키 관리자를 사용하도록하여 불일치가 없도록합니다 .

public class SystemWebCookieManager : ICookieManager
{
    public string GetRequestCookie(IOwinContext context, string key)
    {
        if (context == null)
        {
            throw new ArgumentNullException("context");
        }

        var webContext = context.Get<HttpContextBase>(typeof(HttpContextBase).FullName);
        var cookie = webContext.Request.Cookies[key];
        return cookie == null ? null : cookie.Value;
    }

    public void AppendResponseCookie(IOwinContext context, string key, string value, CookieOptions options)
    {
        if (context == null)
        {
            throw new ArgumentNullException("context");
        }
        if (options == null)
        {
            throw new ArgumentNullException("options");
        }

        var webContext = context.Get<HttpContextBase>(typeof(HttpContextBase).FullName);

        bool domainHasValue = !string.IsNullOrEmpty(options.Domain);
        bool pathHasValue = !string.IsNullOrEmpty(options.Path);
        bool expiresHasValue = options.Expires.HasValue;

        var cookie = new HttpCookie(key, value);
        if (domainHasValue)
        {
            cookie.Domain = options.Domain;
        }
        if (pathHasValue)
        {
            cookie.Path = options.Path;
        }
        if (expiresHasValue)
        {
            cookie.Expires = options.Expires.Value;
        }
        if (options.Secure)
        {
            cookie.Secure = true;
        }
        if (options.HttpOnly)
        {
            cookie.HttpOnly = true;
        }

        webContext.Response.AppendCookie(cookie);
    }

    public void DeleteCookie(IOwinContext context, string key, CookieOptions options)
    {
        if (context == null)
        {
            throw new ArgumentNullException("context");
        }
        if (options == null)
        {
            throw new ArgumentNullException("options");
        }

        AppendResponseCookie(
            context,
            key,
            string.Empty,
            new CookieOptions
            {
                Path = options.Path,
                Domain = options.Domain,
                Expires = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc),
            });
    }
}

응용 프로그램 시작시 OWIN 종속성을 만들 때 지정하십시오.

app.UseCookieAuthentication(new CookieAuthenticationOptions
{
    ...
    CookieManager = new SystemWebCookieManager()
    ...
});

비슷한 답변이 여기에 제공되었지만 문제를 해결하는 데 필요한 모든 코드베이스가 포함되어 있지 않으므로 Katana Project에 대한 외부 링크가 중단 될 수 있으므로 여기에 추가해야합니다. 여기에 해결책으로.


고마워요, 저의 작품이지만이 ControllerContext.HttpContext.Session.RemoveAll ();을 호출하여 모든 세션을 지 웁니다. externallogincallback 함수
adnan

ASP.NET Webforms 4.6.1에 적용 됩니까? 내 ASP.NET Webforms, OWIN, ADFS
웹앱

@Kiquenet 웹 앱에서 OWIN 쿠키를 사용합니까? 그럼요
Alexandru

코드에서 Startup.ConfigureAuth우리는이 app.UseCookieAuthenticationapp.UseWsFederationAuthentication마지막으로하고 app.UseStageMarker
Kiquenet

@Alexandru 당신은 편집을 고려할 수 있습니다, 우리 팀은이 버그를 쳤고 드물고 무작위였습니다 .DEV 및 UAT 환경을 통해 우리에게 숨겨졌습니다. ".NET 쿠키 관리자가 항상 이길 것입니다." OWIN 쿠키가 항상 덮어 쓰여지면 OIDC 미들웨어 중 어느 것도 우리의 개발 워크 스테이션에서 쿠키를 만들지 못했을 것입니다. 그러나 무작위성은 버그로 인해 2 일 동안 프로덕션에 이르기까지 모든 규모를 달성 할 수있었습니다 (내부 용도로는 AAD를 통해 로그인 할 수 없음). 대답에서 "항상"이라는 단어를 제거해도 될까요?
yzorg

17

Katana 팀은 Tomas Dolezar가 제기 한 문제 에 답변하고 해결 방법에 대한 문서를 게시했습니다 .

해결 방법은 두 가지 범주로 나뉩니다. 하나는 System.Web을 재구성하여 Response.Cookies 컬렉션을 사용하지 않고 OWIN 쿠키를 덮어 쓰지 않도록하는 것입니다. 다른 방법은 영향을받는 OWIN 구성 요소를 재구성하여 쿠키를 System.Web의 Response.Cookies 컬렉션에 직접 쓰도록하는 것입니다.

  • 인증 전에 세션이 설정되어 있는지 확인 : System.Web과 Katana 쿠키 간의 충돌은 요청마다 발생하므로 응용 프로그램이 인증 흐름 전에 일부 요청에 대해 세션을 설정할 수 있습니다. 사용자가 처음 도착하면 쉽게 수행 할 수 있지만 세션 또는 인증 쿠키가 만료되거나 새로 고쳐야 할 경우 나중에 보장하기가 더 어려울 수 있습니다.
  • SessionStateModule 비활성화-응용 프로그램이 세션 정보에 의존하지 않지만 세션 모듈이 여전히 위의 충돌을 일으키는 쿠키를 설정하는 경우 세션 상태 모듈을 비활성화하는 것을 고려할 수 있습니다.
  • System.Web의 쿠키 모음에 직접 쓰도록 CookieAuthenticationMiddleware를 다시 구성하십시오.
app.UseCookieAuthentication(new CookieAuthenticationOptions
                                {
                                    // ...
                                    CookieManager = new SystemWebCookieManager()
                                });

문서에서 SystemWebCookieManager 구현을 참조하십시오 (위 링크).

더 자세한 정보는 여기

편집하다

문제를 해결하기 위해 취한 단계 아래 1.와 2.는 모두 별도로 문제를 해결했지만 다음과 같은 경우에 모두 적용하기로 결정했습니다.

1. SystemWebCookieManager 사용

2. 세션 변수를 설정하십시오 :

protected override void Initialize(RequestContext requestContext)
{
    base.Initialize(requestContext);

    // See http://stackoverflow.com/questions/20737578/asp-net-sessionid-owin-cookies-do-not-send-to-browser/
    requestContext.HttpContext.Session["FixEternalRedirectLoop"] = 1;
}

(참고 : 위의 Initialize 메서드는 base.Initialize가 세션을 사용할 수있게하므로 수정의 논리적 위치입니다. 그러나 OpenId에는 먼저 익명 요청이 있으므로 OpenId 공급자로 리디렉션 한 후 다시 수정을 적용 할 수도 있습니다. 수정 프로그램이 첫 번째 익명 요청 중에 세션 변수를 이미 설정 한 상태에서 다시 리디렉션이 발생하기 전에 문제를 해결하는 동안 앱으로 다시 리디렉션 한 후 문제가 발생 함)

편집 2

Katana 프로젝트 에서 복사하여 붙여 넣기 2016-05-14 :

이거 추가 해봐:

app.UseCookieAuthentication(new CookieAuthenticationOptions
                                {
                                    // ...
                                    CookieManager = new SystemWebCookieManager()
                                });

...이:

public class SystemWebCookieManager : ICookieManager
{
    public string GetRequestCookie(IOwinContext context, string key)
    {
        if (context == null)
        {
            throw new ArgumentNullException("context");
        }

        var webContext = context.Get<HttpContextBase>(typeof(HttpContextBase).FullName);
        var cookie = webContext.Request.Cookies[key];
        return cookie == null ? null : cookie.Value;
    }

    public void AppendResponseCookie(IOwinContext context, string key, string value, CookieOptions options)
    {
        if (context == null)
        {
            throw new ArgumentNullException("context");
        }
        if (options == null)
        {
            throw new ArgumentNullException("options");
        }

        var webContext = context.Get<HttpContextBase>(typeof(HttpContextBase).FullName);

        bool domainHasValue = !string.IsNullOrEmpty(options.Domain);
        bool pathHasValue = !string.IsNullOrEmpty(options.Path);
        bool expiresHasValue = options.Expires.HasValue;

        var cookie = new HttpCookie(key, value);
        if (domainHasValue)
        {
            cookie.Domain = options.Domain;
        }
        if (pathHasValue)
        {
            cookie.Path = options.Path;
        }
        if (expiresHasValue)
        {
            cookie.Expires = options.Expires.Value;
        }
        if (options.Secure)
        {
            cookie.Secure = true;
        }
        if (options.HttpOnly)
        {
            cookie.HttpOnly = true;
        }

        webContext.Response.AppendCookie(cookie);
    }

    public void DeleteCookie(IOwinContext context, string key, CookieOptions options)
    {
        if (context == null)
        {
            throw new ArgumentNullException("context");
        }
        if (options == null)
        {
            throw new ArgumentNullException("options");
        }

        AppendResponseCookie(
            context,
            key,
            string.Empty,
            new CookieOptions
            {
                Path = options.Path,
                Domain = options.Domain,
                Expires = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc),
            });
    }
}

이 답변이 훨씬 간단하고 문제를 해결하기 쉽다는 것을 알았습니다. 고마워-어쩌면 내가 너무 갑자기 말했어 이것은 내 문제를 해결하지 못했습니다.
JCS

@JCS 문제를 해결하기 위해 취한 단계가 포함되었습니다. 문제가 관련되어 있는지 확인 했습니까?
thomius

인증을 위해 세션 관리를 위해 Web Api 2 + Owin 미들웨어 + redis 캐시를 사용하고 있습니다. SystemWebCookieManager를 사용하려고 시도했지만 인증 쿠키가 설정되지 않은 문제를 해결하지 못했습니다. "UseKentorOwinCookieSaver"를 사용하면 문제가 해결되었지만 추가 외부 종속성을 좋아하지는 않습니다.
JCS

세션을 지우는 것이 나를 위해 일했습니다. 외부 의존성이 필요하지 않습니다. 을 호출하기 전에이 작업을 수행 ControllerContext.HttpContext.Session.RemoveAll();하십시오 . 이것이 최상의 솔루션인지는 모르겠지만 가장 간단합니다. ExternalLogin()ChallengeResult()
Alisson

1
@chemitaxis 확실히, (무조건 ?.연산자)는 C # 6에서만 작동합니다.
Alisson

5

답변이 이미 제공되었지만 owin 3.1.0에는 사용할 수있는 SystemWebChunkingCookieManager 클래스가 있습니다.

https://github.com/aspnet/AspNetKatana/blob/dev/src/Microsoft.Owin.Host.SystemWeb/SystemWebChunkingCookieManager.cs

https://raw.githubusercontent.com/aspnet/AspNetKatana/c33569969e79afd9fb4ec2d6bdff877e376821b2/src/Microsoft.Owin.Host.SystemWeb/SystemWebChunkingCookieManager.cs

app.UseCookieAuthentication(new CookieAuthenticationOptions
{
    ...
    CookieManager = new SystemWebChunkingCookieManager()
    ...
});

이것은 여전히 ​​3.1.0에서 문제입니까?
cyberconte

1
예, 여전히 3.1.0에서 문제이며 기본 쿠키는 여전히 ChunkingCookieManager이므로이 쿠키 관리자가 필요했습니다.
jonmeyer

어디에서 사용할 수 있습니까? 그리고 어떻게?
Simon_Weaver

@jonmeyer 감사합니다. 나는 어제 SystemCCM과 CCM의 차이점을 놓쳤다 고 생각하므로이를 확실히 확인할 것입니다.
Simon_Weaver

위의 줄을 추가 한 후에도 작동하지 않습니다. 3.1.0 버전을 사용하고 있습니다. 주로 처음 로그인 할 수는 있지만 로그 아웃 후에는 로그인 할 수 없습니다.
Mitin Dixit

3

OWIN 미들웨어에서 쿠키를 직접 설정하는 경우 사용 OnSendingHeaders하면 문제가 해결되는 것 같습니다.

예를 들어, 아래 코드를 사용 하지 owinResponseCookie2않아도 설정됩니다 owinResponseCookie1.

private void SetCookies()
{
    var owinContext = HttpContext.GetOwinContext();
    var owinResponse = owinContext.Response;

    owinResponse.Cookies.Append("owinResponseCookie1", "value1");

    owinResponse.OnSendingHeaders(state =>
    {
        owinResponse.Cookies.Append("owinResponseCookie2", "value2");
    },
    null);

    var httpResponse = HttpContext.Response;
    httpResponse.Cookies.Remove("httpResponseCookie1");
}

3

Visual Studio 2017.net MVC 5.2.4 와 비슷한 문제에 직면하여 Nuget Microsoft.Owin.Security.Google 을 최신 4.0.1 로 최신 버전으로 업데이트하면 나를 위해 일했습니다! 이것이 누군가를 돕기를 바랍니다!


1
이것에 내 베이컨을 저장했습니다! Android Chrome에서 특별히 인증이 임의로 손실되는 문제가있었습니다. 이 스레드에서 다른 것은 작동하지 않았습니다. 내가 VS2019 및 ASP MVC (5)를 사용하고 있습니다
zfrank

2

가장 빠른 한 줄 코드 솔루션 :

HttpContext.Current.Session["RunSession"] = "1";

CreateIdentity 메소드 앞에 다음 행을 추가하십시오.

HttpContext.Current.Session["RunSession"] = "1";
var userIdentity = userManager.CreateIdentity(user, DefaultAuthenticationTypes.ApplicationCookie);
_authenticationManager.SignIn(new AuthenticationProperties { IsPersistent = rememberLogin }, userIdentity);

1
이 코드를 어디에 넣었 HttpContext.Current.Session["RunSession"] = "1";습니까? 에서 Globa.asax Session_Start ?
Kiquenet

1
실제로 사용 가능한 가장 간단하고 빠른 솔루션이며 해당 문제의 솔루션이 프레임 워크에 포함되지 않을 때까지 (이미 발표 할 것입니다.) 예를 들어 클래스 + 종속성 대신 하나의 라이너를 선호합니다. . 이 솔루션은 과소 평가 된 IMHO입니다.
Der Zinger

IssueAuthToken 메소드의 상단에있는 AuthManager에 추가했습니다
Alexander Trofimov

1

Set-Cookie 헤더와 동일한 증상이 전송되지 않았지만 이러한 답변 중 어느 것도 도움이되지 않았습니다. 모든 것이 로컬 컴퓨터에서 작동했지만 프로덕션에 배포되면 set-cookie 헤더가 설정되지 않습니다.

WebApi 압축 지원CookieAuthenticationMiddleware 과 함께 WebApi와 함께 사용자 정의 를 사용하는 조합이었습니다.

운 좋게도 프로젝트에서 ELMAH를 사용 하여이 예외가 기록되도록했습니다.

HTTP 헤더가 전송 된 후 System.Web.HttpException 서버가 헤더를 추가 할 수 없습니다.

GitHub 문제로 연결되었습니다

기본적으로 내 것과 같은 이상한 설정이있는 경우 쿠키를 설정하는 WebApi 컨트롤러 / 방법에 대한 압축비활성화 하거나을 시도하십시오 OwinServerCompressionHandler.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.