2016-03-31 2 views
2

Куда пропало мое печенье?Формы Auth: Где мой auth cookie ушел?

При перенаправлении от моего SSO к клиентскому приложению, то .ASPXAUTH печенье теряется, но только тогда, когда два сайта не на том же сервере.

В Fiddler я вижу, что cookie устанавливается SSO для ответа в правильном пути к файлу cookie для клиентского приложения. Однако при перенаправлении я вижу, что запрос не несет cookie.

Response после входа в систему единого входа

Response after logging into SSO

Запрос обратно в клиентское приложение: Request back to client application

Соответствующие разделы Логина приложения web.config:

<machineKey compatibilityMode="Framework20SP2" 
       decryption="AES" 
       decryptionKey="<a valid RSA key>" 
       validation="SHA1" 
       validationKey="<a valid HMACSHA256 hash>" 
       /> 
    <!-- "SHA1" actually implements HMACSHA256, but for one reason or another, we can't specify it explicitly. --> 

    <authentication mode="Forms"> 
     <forms loginUrl="Index" 
      cookieless="UseCookies" 
      requireSSL="false" 
      name=".ASPXAUTH" 
      path="/path/to/SSO-Virtual-Directory/" 
      slidingExpiration="true" 
      timeout="20" 
      enableCrossAppRedirects="true" 
      protection="All" 
      ticketCompatibilityMode="Framework20" 
      /> 
     <!-- set cookie path relative to virtual path of the application in IIS. See Application -> Advanced Settings to see the virtual path. 
      Cookie Paths, Domains, and Names are all CASE SENSITIVE!!!!! 
      Be sure to check the virtual path, as it doesn't update when you rename path tokens to change case. you will have to recreate the application to update the virtualpath--> 
    </authentication> 

    <!--SSOConfig Providers--> 
    <membership defaultProvider="SqlMembershipProvider" > 
     <providers> 
     <clear /> 
     <add name="ADMembershipProvider" 
      connectionStringName="ADConnectionString" 
      attributeMapUsername="sAMAccountName" 
      enableSearchMethods="false" 
      connectionUsername="<a valid domain username" 
      connectionPassword="<a valid password>" 
      type="System.Web.Security.ActiveDirectoryMembershipProvider" 
      /> 
     <!-- do not set applicationName= .--> 

     <add name="SqlMembershipProvider" 
      connectionStringName="SqlConnectionString" 
      applicationName="SSO" 
      enablePasswordRetrieval="false" 
      enablePasswordReset="true" 
      requiresQuestionAndAnswer="true" 
      requiresUniqueEmail="true" 
      passwordFormat="Hashed" 
      minRequiredNonalphanumericCharacters="0" 
      type="System.Web.Security.SqlMembershipProvider" 
      /> 
     <!-- for some messed up reason applicationName is required.--> 
     </providers> 
    </membership> 

    <roleManager defaultProvider="SqlRoleProvider" 
       enabled="true" 
       cacheRolesInCookie="true" 
       cookieName=".ASPROLES" 
       cookieTimeout="30" 
       cookiePath="/path/to/Virtual-Directory/" 
       cookieRequireSSL="false" 
       cookieSlidingExpiration="true" 
       cookieProtection="All" 
       > 
     <!--set cookie path relative to virtual path of the application in IIS. See Application -> Advanced Settings to see the virtual path. eg: /secure/sso/CentralLogin/ on Exodus. 
      Cookie Paths, Domains, and Names are all CASE SENSITIVE!!!!! 
      Be sure to check the virtual path, as it doesn't update when you rename path tokens to change case. you will have to recreate the application to update the virtualpath--> 
     <providers> 
     <clear /> 
     <add name="SqlRoleProvider" 
      type="System.Web.Security.SqlRoleProvider" 
      connectionStringName="SqlConnectionString" 
      applicationName="SSO" 
      /> 
     <!-- set ApplicationName--> 
     </providers> 
    </roleManager> 

Client Web .config:

<machineKey compatibilityMode="Framework20SP2" 
       decryptionKey="<The same RSA key>" 
       validation="SHA1" 
       validationKey="<The same HMACSHA256 hash>" 
    /> 

    <authentication mode="Forms" > 
     <forms loginUrl="~/login/Index" 
      name=".ASPXAUTH" 
      path="/Payment/" 
      requireSSL="false" 
      slidingExpiration="true" 
      timeout="20" 
      cookieless="UseCookies" 
      enableCrossAppRedirects="true" 
      protection="All" 
      ticketCompatibilityMode="Framework20" 
      /> 
    </authentication> 

    <membership defaultProvider="SqlMembershipProvider" > 
     <providers> 
     <clear /> 
     <add name="ADMembershipProvider" 
      connectionStringName="ADConnectionString" 
      attributeMapUsername="sAMAccountName" 
      enableSearchMethods="true" 
      connectionUsername="<a valid domain username" 
      connectionPassword="<a valid password>" 
      type="System.Web.Security.ActiveDirectoryMembershipProvider" 
      /> 

     <add name="SqlMembershipProvider" 
      connectionStringName="SqlSSOConnection" 
      applicationName="SSO" 
      enablePasswordRetrieval="false" 
      enablePasswordReset="true" 
      requiresQuestionAndAnswer="true" 
      requiresUniqueEmail="true" 
      passwordFormat="Hashed" 
      minRequiredNonalphanumericCharacters="0" 
      type="System.Web.Security.SqlMembershipProvider" 
      /> 
     </providers> 
    </membership> 

    <roleManager defaultProvider="SqlRoleProvider" 
       enabled="true" 
       cacheRolesInCookie="true" 
       cookieName=".ASPROLES" 
       cookieTimeout="30" 
       cookiePath="/Payment/" 
       cookieRequireSSL="false" 
       cookieSlidingExpiration="true" 
       cookieProtection="All" 
        > 
     <providers> 
     <clear /> 
     <add name="SqlRoleProvider" 
      type="System.Web.Security.SqlRoleProvider" 
      connectionStringName="SqlSSOConnection" 
      applicationName="SSO" 
      /> 
     </providers> 
    </roleManager> 

Оба сайта: MVC5 on .Net 4.5.2.

У кого-нибудь есть идеи относительно того, что происходит не так, и что я могу с этим поделать?

+0

И почему он должен присутствовать? Как я понимаю из вашего описания, это cookie для домена SSO, поэтому, если ваше клиентское приложение находится в домене, отличном от SSO, браузер не будет передавать SSO-файлы по запросу в ваше клиентское приложение. – Evk

+0

@Evk, ну, на самом деле, как должна работать аутентификация форм. Я могу подтвердить это с помощью Fiddler, используя наш существующий SSO. Обратите внимание, что настройки домена для региона Forms не определены, и когда я смотрю на необработанные записи, у них есть Domain of "", который необходим для перенаправления на адрес localhost: 7999. Однако файлы cookie помещаются в правильный путь (подтвержденный скриптом) для клиентского приложения. Вы предлагаете какой-либо конкретный курс действий? –

+0

Пустой домен просто означает «использовать домен запроса», поэтому он будет отображаться в любой домен, к которому вы обращались. Вопрос в том, что ваш клиент и SSO разделяют домен верхнего уровня (например, клиент - some.thing.com и SSO - вещь.com), или они находятся на совершенно разных доменах. Если последний - ваш cookie из SSO не будет отправлен вашему клиенту. – Evk

ответ

4

Так как мы обнаружили в комментариях, проблема заключается в том, что SSO и клиент находятся на разных доменах \ ips, и поэтому набор cookie для SSO не будет передаваться клиенту браузером. Существуют различные способы решения этой проблемы, но они требуют изменения того, как работает ваш общий SSO-процесс.

Как я понимаю, у вас есть только проблемы с этим в среде разработки, а не на производстве. Если да, предположим, что ваше SSO находится на 10.0.0.1, а ваш клиент находится на 127.0.0.1. Затем сопоставьте домен client.yoursite.local (в корпоративном DNS или только в файле/etc/hosts) до 127.0.0.1 и yoursite.local до 10.0.0.1 и используйте имена доменов вместо необработанных IP-адресов. Затем в SSO установите cookie с доменом «.yoursite.local». Затем это должно быть правильно доставлено вашему клиентскому приложению и не потребует значительных изменений в том, как работает ваш SSO-процесс.

+0

Это очень разумное решение. Я уйду с этим, и посмотрю, куда меня ведет. Другая альтернатива, которую я изучал, заключается в передаче значения cookie в querystring, которое выглядит многообещающим, но является довольно грубым решением, и его следует избегать, если это возможно. –

+0

@FrankThomas - вы также можете вручную добавить его в заголовок http. – Igor

+0

Добавление его в строку запроса * крайне плохой *. Этот cookie - это то, что разрешает пользователю, поэтому его следует постоянно защищать. HTTPS будет защищать файл cookie обычно, потому что он отправляется как заголовок запроса, который зашифрован. Единственное, что HTTPS * не может * зашифровать, это сам URL-адрес, в которое ваше решение будет включать значение cookie. Любой, кто нюхает сеть, может принять значение из запроса и предположить, что учетная запись пользователя. –

Смежные вопросы