net mvc example asp c# asp.net asp.net-mvc oauth-2.0 dotnetopenauth

c# - example - DotNetOpenAuth no funciona con MVC 5 RC



oauth2 server c# example (5)

Después de depurar y hablar con la gente de DotNetOpenAuth en GitHub https://github.com/DotNetOpenAuth/DotNetOpenAuth/issues/307 la conclusión es que MVC 5 tiene un nuevo modelo de seguridad.

La redirección de enlace, por lo tanto, no será suficiente. Hasta más allá hay dos opciones:

1) Toma el código fuente DotNetOpenAuth y elimina el [assembly: AllowPartiallyTrustedCallers] de todos los proyectos. Recompile y miembro para deshabilitar la verificación de nombre fuerte sn -Vr *. Después de este código no se puede ejecutar en entornos de confianza media.

2) Toma el código fuente de DotNetOpenAuth y recompilalo contra MVC 5.

De acuerdo con la discusión sobre GitHub, la mejor solución para el futuro sería trasladar todas las cosas relacionadas de MVC a un ensamble por separado.

He estado trabajando mucho con DotNetOpenAuth. Primero usamos 5.0.0-alpha1 pero cambiamos a v4.0.30319 porque no pudimos encontrar lo que causaba nuestros problemas.

Estamos construyendo un proyecto de API web de C # en .NET 4.5.1 RC con MVC 5 RC en Visual Studio 2013. Hemos implementado IAuthorizationServerHost , INonceStore e ICryptoKeyStore .

El problema que tenemos está alrededor del siguiente caso:

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(); un método con orígenes en DotNetOpenAuth.Messaging y la clase estática MessagingUtilities . El DotNetOpenAuth.Core (que contiene este código) hace referencia a MVC 4.0 y la clase HttpResponseMessageActionResult hereda de ActionResult .

Esto significa que la versión actual de DotNetOpenAuth no es compatible con MVC 5. Compilar e intentar ejecutar esto solo presentará 500 errores.

¿Alguien tiene alguna idea de cómo esto podría solucionarse fácilmente (o quizás no)?

No noté que el paquete DotNetOpenAuth Nuget escribió sobre mis paquetes para 5.0. Entonces, después de volver a instalar los paquetes y agregar AssemblyBinding nuevamente:

<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>

Esto nos llevó un poco más allá. Ahora el error se reduce a:

Intento por el método transparente de seguridad ''DotNetOpenAuth.Messaging.MessagingUtilities.AsActionResult (DotNetOpenAuth.Messaging.OutgoingWebResponse)'' para acceder al tipo de seguridad crítica ''System.Web.Mvc.ActionResult'' falló.


Fix disponible.

Instale el paquete NuGet DotNetOpenAuth.Mvc5 y cambie todos los usos de AsActionResult() a AsActionResultMvc5()


Si lo usa con OutgoingWebresponse (no actualizó dotnetOpenAuth pero mvc yes a 5).

Agregue esta clase (pirateada de la respuesta de ):

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(); } } }

Y luego reemplaza:

return response.AsActionResult ();

con

return new WrapperHttpResponseMessageResult (respuesta);


Una solución alternativa (se puede usar con el paquete beta nuget actual) para este caso:

  • Crear una clase ActionResult ajusta 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(); } } }

  • Cambiar el resultado return outgoingWebResponse.AsActionResult(); al new WrapperHttpResponseMessageResult(outgoingWebResponse);

El código de WrapperHttpResponseMessageResult se copia de AsActionResult , por lo que realizan la misma función.


utilice esto para asegurarse de que el autorizador se pase correctamente.

public class MvcAuthorizer : WebAuthorizer { public ActionResult BeginAuthorization() { return new MvcOAuthActionResult(this); } public new ActionResult BeginAuthorization(Uri callback) { this.Callback = callback; return new MvcOAuthActionResult(this); } }

''luego recuperarlo correctamente

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); } }