Ответ 1
Исправлено.
Установите пакет NuGet DotNetOpenAuth.Mvc5 и измените все виды использования AsActionResult()
на AsActionResultMvc5()
Я много работал с DotNetOpenAuth. Сначала мы использовали 5.0.0-alpha1, но мы перешли на v4.0.30319, потому что мы не могли найти, что вызвало наши проблемы.
Мы строим проект веб-API С# на .NET 4.5.1 RC с MVC 5 RC в Visual Studio 2013. Мы реализовали IAuthorizationServerHost
, INonceStore
и ICryptoKeyStore
.
Проблема, которую мы имеем, касается следующего случая:
public class TokensController : Controller
{
private readonly AuthorizationServer authorizationServer = new AuthorizationServer(new MyAuthorizationServer());
/// <summary>
/// This action will handle all token requests.
/// </summary>
/// <returns>The action result that will output the token response.</returns>
[HttpPost]
public ActionResult Index()
{
var outgoingWebResponse = this.authorizationServer.HandleTokenRequest(this.Request);
return outgoingWebResponse.AsActionResult();
}
}
return outgoingWebResponse.AsActionResult();
метод с истоками в DotNetOpenAuth.Messaging
и статический класс MessagingUtilities
. DotNetOpenAuth.Core
(который содержит этот код) ссылается на MVC 4.0 и класс HttpResponseMessageActionResult
наследует от ActionResult
.
Это означает, что текущая версия DotNetOpenAuth несовместима с MVC 5. Компиляция и попытка запустить это будут только случаи 500 ошибок.
Есть ли у кого-нибудь идеи, как это может быть легко исправлено (или, может быть, нет)?
Я не заметил, что пакет DotNetOpenAuth Nuget написал мои пакеты для 5.0. Поэтому после переустановки пакетов и добавления сборки снова необходимо:
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" />
<bindingRedirect oldVersion="1.0.0.0-4.0.0.0" newVersion="5.0.0.0" />
</dependentAssembly>
</assemblyBinding>
Это привело нас немного дальше. Теперь ошибка сводится к:
Попытка прозрачным методом безопасности "DotNetOpenAuth.Messaging.MessagingUtilities.AsActionResult(DotNetOpenAuth.Messaging.OutgoingWebResponse)" для доступа к критическому типу безопасности "System.Web.Mvc.ActionResult" не удалось.
Исправлено.
Установите пакет NuGet DotNetOpenAuth.Mvc5 и измените все виды использования AsActionResult()
на AsActionResultMvc5()
После дальнейшей отладки и общения с людьми в DotNetOpenAuth в GitHub https://github.com/DotNetOpenAuth/DotNetOpenAuth/issues/307 вывод заключается в том, что MVC 5 имеет новую модель безопасности.
Переадресации связывания, следовательно, будет недостаточно. Пока еще есть два варианта:
1) Захватите исходный код DotNetOpenAuth и удалите [сборка: AllowPartiallyTrustedCallers] из всех проектов. Перекомпилируйте и выберите член, чтобы отключить проверку подлинности имени sn -Vr *. После того, как этот код не может быть запущен в средах среднего доверия.
2) Захватите исходный код DotNetOpenAuth и перекомпилируйте его с MVC 5.
В соответствии с обсуждением GitHub лучшим решением будущего будет перемещение всех связанных материалов MVC в отдельную сборку.
Обходной путь (может использоваться с текущим пакетом beta nuget) для этого случая:
Создайте обертки класса ActionResult HttpResponseMessage
public class WrapperHttpResponseMessageResult : ActionResult
{
private readonly HttpResponseMessage _response;
public WrapperHttpResponseMessageResult(HttpResponseMessage response)
{
_response = response;
}
public override void ExecuteResult(ControllerContext context)
{
HttpResponseBase responseContext = context.RequestContext.HttpContext.Response;
responseContext.StatusCode = (int)_response.StatusCode;
responseContext.StatusDescription = _response.ReasonPhrase;
foreach (KeyValuePair<string, IEnumerable<string>> keyValuePair in (HttpHeaders)_response.Headers)
{
foreach (string str in keyValuePair.Value)
responseContext.AddHeader(keyValuePair.Key, str);
}
if (_response.Content != null)
{
_response.Content.CopyToAsync(responseContext.OutputStream).Wait();
}
}
}
Измените return outgoingWebResponse.AsActionResult();
на new WrapperHttpResponseMessageResult(outgoingWebResponse);
Код WrapperHttpResponseMessageResult
скопирован из AsActionResult
, поэтому они выполняют ту же функцию.
используйте это, чтобы убедиться, что авторизатор прошел правильно.
public class MvcAuthorizer : WebAuthorizer
{
public ActionResult BeginAuthorization()
{
return new MvcOAuthActionResult(this);
}
public new ActionResult BeginAuthorization(Uri callback)
{
this.Callback = callback;
return new MvcOAuthActionResult(this);
}
}
', затем верните его правильно
public class MvcOAuthActionResult : ActionResult
{
private readonly WebAuthorizer webAuth;
public MvcOAuthActionResult(WebAuthorizer webAuth)
{
this.webAuth = webAuth;
}
public override void ExecuteResult(ControllerContext context)
{
webAuth.PerformRedirect = authUrl =>
{
HttpContext.Current.Response.Redirect(authUrl);
};
Uri callback =
webAuth.Callback == null ?
HttpContext.Current.Request.Url :
webAuth.Callback;
webAuth.BeginAuthorization(callback);
}
}
Если вы используете его с OutgoingWebresponse (не обновляете dotnetOpenAuth, а mvc да до 5).
Добавьте этот класс (взломанный из langtu):
public class WrapperHttpResponseMessageResult : ActionResult
{
private readonly OutgoingWebResponse _response;
public WrapperHttpResponseMessageResult(OutgoingWebResponse response)
{
_response = response;
}
public override void ExecuteResult(ControllerContext context)
{
HttpResponseBase responseContext = context.RequestContext.HttpContext.Response;
responseContext.StatusCode = (int)_response.Status;
responseContext.StatusDescription = _response.Status.ToString();
foreach (string key in _response.Headers.Keys)
{
responseContext.AddHeader(key, _response.Headers[key]);
}
if (_response.Body != null)
{
StreamWriter escritor = new StreamWriter(responseContext.OutputStream);
escritor.WriteAsync(_response.Body).Wait();
}
}
}
И затем замените:
return response.AsActionResult();
с
вернуть новый WrapperHttpResponseMessageResult (ответ);