Вопрос

Я получаю исключение «Подпись сообщения» была неверной », когда пытался аутентифицировать подлинность с миопенидом и Yahoo.

Я использую в значительной степени образец примера ASP.NET MVC, который поставлялся с DotNetoPenauth 3.4.2

public ActionResult Authenticate(string openid)
{
    var openIdRelyingParty = new OpenIdRelyingParty();
    var authenticationResponse = openIdRelyingParty.GetResponse();

    if (authenticationResponse == null)
    {
        // Stage 2: User submitting identifier
        Identifier identifier;

        if (Identifier.TryParse(openid, out identifier))
        {
            var realm = new Realm(Request.Url.Root() + "openid");
            var authenticationRequest = openIdRelyingParty.CreateRequest(openid, realm);
            authenticationRequest.RedirectToProvider();
        }
        else
        {
            return RedirectToAction("login", "home");
        }
    }
    else
    {
        // Stage 3: OpenID provider sending assertion response
        switch (authenticationResponse.Status)
        {
            case AuthenticationStatus.Authenticated:
            {
                // TODO
            }
            case AuthenticationStatus.Failed:
            {
                throw authenticationResponse.Exception;
            }
        }
    }

    return new EmptyResult();
}

Хорошо работая с Google, AOL и другими. Тем не менее, Yahoo и Myopenid попадают в AuthenticationStatus.failed Case с следующим исключением:

DotNetOpenAuth.Messaging.Bindings.InvalidSignatureException: Message signature was incorrect.
   at DotNetOpenAuth.OpenId.ChannelElements.SigningBindingElement.ProcessIncomingMessage(IProtocolMessage message) in c:\Users\andarno\git\dotnetopenid\src\DotNetOpenAuth\OpenId\ChannelElements\SigningBindingElement.cs:line 139
   at DotNetOpenAuth.Messaging.Channel.ProcessIncomingMessage(IProtocolMessage message) in c:\Users\andarno\git\dotnetopenid\src\DotNetOpenAuth\Messaging\Channel.cs:line 992
   at DotNetOpenAuth.OpenId.ChannelElements.OpenIdChannel.ProcessIncomingMessage(IProtocolMessage message) in c:\Users\andarno\git\dotnetopenid\src\DotNetOpenAuth\OpenId\ChannelElements\OpenIdChannel.cs:line 172
   at DotNetOpenAuth.Messaging.Channel.ReadFromRequest(HttpRequestInfo httpRequest) in c:\Users\andarno\git\dotnetopenid\src\DotNetOpenAuth\Messaging\Channel.cs:line 386
   at DotNetOpenAuth.OpenId.RelyingParty.OpenIdRelyingParty.GetResponse(HttpRequestInfo httpRequestInfo) in c:\Users\andarno\git\dotnetopenid\src\DotNetOpenAuth\OpenId\RelyingParty\OpenIdRelyingParty.cs:line 540

Похоже, что у других такая же проблема: http://trac.dotnetopenauth.net:8000/ticket/172

У кого -нибудь есть обходной путь?

Это было полезно?

Решение

Оказывается, это было проблемой с использованием Dotnetopenauth в среде веб -фермы.

Когда вы создаете свой OpenIdelyingParty, убедитесь, что вы передаете NULL в конструкторе.

Это ставит ваш веб -сайт в Openid без сохранения состояния или «тупой» режим. Пользователям немного медленнее входить в систему (если вы даже заметите), но вы избегаете необходимости писать reelyingPartyApplicationStore, чтобы DotNetoPenauth работал на вашей ферме;

var openIdRelyingParty = new OpenIdRelyingParty(null);

Другие советы

Все это обсуждение вращается вокруг следующего вопроса:

Как полагаться на сторону (RP) убедится, что запрос, содержащий токен аутентификации, поступает от OP (OpenID -поставщик), которому он отправил запрос пользователя?

Следующие шаги объясняют, как это происходит

  1. Запрос пользователя приходит на ответную сторону (RP), наш веб -сайт в нашем случае
  2. Приложение хранит уникальную подпись, соответствующую этому пользователю в локальном магазине подписи (LSS), а затем встраивает эту подпись в сообщение и перенаправляет это сообщение в OpenID Provider (OP)
  3. Пользователь печатает свои учетные данные, а OP подлинности подлинности, а затем пересылает это сообщение, в котором подпись все еще встроена в него, обратно в RP
  4. RP Сравните подпись, которая встроена в сообщение с подписью, которая находится в LSS, и если они соответствуют RP аутентификации пользователя

Если LSS исчезает (каким -то образом) до того, как сообщение возвращается из OP, для RP нет ничего, чтобы сравнить подпись с таким образом, поэтому оно не может аутентифицировать пользователя и ошибки отбрасывает: подпись сообщения была неверной.

Как LSS может исчезнуть:

  1. ASP.NET обновляет пул приложений
  2. IIS перезапускается
  3. В веб -ферме сообщение обслуживается приложением, размещенным на разных сервере

Два решения этой проблемы:

  1. RP -беги в тупой режиме

    а Он не хранит и подписывается локально и, следовательно, не использует сравнение подписи, чтобы убедиться, что сообщение поступает из ОП, к которому он направил пользователя для аутентификации

    беременный Вместо этого, как только RP получил сообщение об аутентификации от OP, он отправил сообщение обратно в OP и попросил его проверить, является ли он тем, кто проверяет этого пользователя и является создателем сообщения. Если ОП отвечает да, я - инициатор этого сообщения, и я создал это сообщение, тогда пользователь аутентифицируется RP

  2. Реализуйте свой собственный магазин настойчивости, который не исчезает, что не имеет значения, что ASP.NET делает с процессом, так же, как использование SQL для хранения состояния сеанса.

Мы исправили эту проблему, внедрив IRelyingPartyApplicationStore (IOpenIdApplicationStore В более новых версиях Dotnetopenauth) и добавление названия класса магазина в .config

<dotNetOpenAuth>
  <openid ...>
    <relyingParty>
      ...
      <store type="some.name.space.MyRelyingPartyApplicationStore, some.assembly"/>
    </relyingParty>
  </openid>
  ...
</dotNetOpenAuth>

Интерфейс представляет собой композицию двух других интерфейсов с пятью членами все вместе.

/// <summary>
/// A hybrid of the store interfaces that an OpenID Provider must implement, and
/// an OpenID Relying Party may implement to operate in stateful (smart) mode.
/// </summary>
public interface IOpenIdApplicationStore : ICryptoKeyStore, INonceStore
{
}

Мы использовали тупой режим в качестве быстрого решения, чтобы встать на работу, но в конце концов, вы, вероятно, захотите что -то подобное.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top