Dotnetopenauth: подпись сообщения была неверной
-
22-09-2019 - |
Вопрос
Я получаю исключение «Подпись сообщения» была неверной », когда пытался аутентифицировать подлинность с миопенидом и 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 -поставщик), которому он отправил запрос пользователя?
Следующие шаги объясняют, как это происходит
- Запрос пользователя приходит на ответную сторону (RP), наш веб -сайт в нашем случае
- Приложение хранит уникальную подпись, соответствующую этому пользователю в локальном магазине подписи (LSS), а затем встраивает эту подпись в сообщение и перенаправляет это сообщение в OpenID Provider (OP)
- Пользователь печатает свои учетные данные, а OP подлинности подлинности, а затем пересылает это сообщение, в котором подпись все еще встроена в него, обратно в RP
- RP Сравните подпись, которая встроена в сообщение с подписью, которая находится в LSS, и если они соответствуют RP аутентификации пользователя
Если LSS исчезает (каким -то образом) до того, как сообщение возвращается из OP, для RP нет ничего, чтобы сравнить подпись с таким образом, поэтому оно не может аутентифицировать пользователя и ошибки отбрасывает: подпись сообщения была неверной.
Как LSS может исчезнуть:
- ASP.NET обновляет пул приложений
- IIS перезапускается
- В веб -ферме сообщение обслуживается приложением, размещенным на разных сервере
Два решения этой проблемы:
RP -беги в тупой режиме
а Он не хранит и подписывается локально и, следовательно, не использует сравнение подписи, чтобы убедиться, что сообщение поступает из ОП, к которому он направил пользователя для аутентификации
беременный Вместо этого, как только RP получил сообщение об аутентификации от OP, он отправил сообщение обратно в OP и попросил его проверить, является ли он тем, кто проверяет этого пользователя и является создателем сообщения. Если ОП отвечает да, я - инициатор этого сообщения, и я создал это сообщение, тогда пользователь аутентифицируется RP
Реализуйте свой собственный магазин настойчивости, который не исчезает, что не имеет значения, что 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
{
}
Мы использовали тупой режим в качестве быстрого решения, чтобы встать на работу, но в конце концов, вы, вероятно, захотите что -то подобное.