2013-09-25 20 views
37

Ho lavorato molto con DotNetOpenAuth. Per prima cosa abbiamo usato 5.0.0-alpha1 ma siamo passati alla v4.0.30319 perché non siamo stati in grado di trovare ciò che stava causando i nostri problemi.DotNetOpenAuth non funziona con MVC 5 RC

Stiamo costruendo un progetto API Web C# su .NET 4.5.1 RC con MVC 5 RC in Visual Studio 2013. Abbiamo implementato IAuthorizationServerHost, INonceStore e ICryptoKeyStore.

Il problema che abbiamo sono intorno il seguente 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 metodo con origini nel DotNetOpenAuth.Messaging e la classe statica MessagingUtilities. Lo DotNetOpenAuth.Core (che contiene questo codice) fa riferimento a MVC 4.0 e alla classe HttpResponseMessageActionResult eredita da ActionResult.

Ciò significa che la versione corrente di DotNetOpenAuth non è compatibile con MVC 5. La compilazione e il tentativo di eseguire ciò causerà solo 500 errori.

Qualcuno ha qualche idea su come questo possa essere risolto facilmente (o forse no)?

Non ho notato che il pacchetto DotNetOpenAuth Nuget ha scritto sui miei pacchetti per 5.0. Quindi dopo aver reinstallato i pacchetti e aggiunto nuovamente l'assemblaggio:

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

Questo ci ha un po 'oltre. Ora l'errore si riduce a:

Tentativo dalla sicurezza metodo trasparente 'DotNetOpenAuth.Messaging.MessagingUtilities.AsActionResult (DotNetOpenAuth.Messaging.OutgoingWebResponse)' di accesso di sicurezza di tipo critico 'System.Web.Mvc.ActionResult' non riuscita.

risposta

6

Dopo ulteriore debug e parlando con le persone a DotNetOpenAuth presso GitHub https://github.com/DotNetOpenAuth/DotNetOpenAuth/issues/307 la conclusione è che MVC 5 ha un nuovo modello di sicurezza.

Il reindirizzamento del binding non sarà quindi sufficiente. Fino a quando ci sono due alternative:

1) Prendere il codice sorgente DotNetOpenAuth e rimuovere [assembly: AllowPartiallyTrustedCallers] da tutti i progetti. Ricompilare e membro per disabilitare la verficazione del nome forte sn -Vr *. Dopo questo codice non può essere eseguito su ambienti Medium Trust.

2) afferrare il codice sorgente e ricompilare DotNetOpenAuth contro MVC 5.

Secondo la discussione su GitHub la soluzione migliore futuro sarebbe spostando fuori tutta roba MVC relative a un assembly separato.

+0

Ho appena eseguito l'aggiornamento a MVC5 e mi sono imbattuto in questo problema. Guardandomi attorno sono stato sorpreso di scoprire che AA ha abbandonato il progetto. Non posso davvero dire che DNOA è ancora in fase di sviluppo perché non esiste un rilascio da molto tempo. Qual è lo stato del progetto? Stai ancora usando DNOA? – Jammer

3

Una soluzione (può usare con il pacchetto beta NuGet corrente) per questo caso:

  • creare una classe ActionResult avvolge 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(); 
         } 
        } 
    } 
    
  • Change return outgoingWebResponse.AsActionResult(); al new WrapperHttpResponseMessageResult(outgoingWebResponse);

Il codice di WrapperHttpResponseMessageResult viene copiato da AsActionResult, quindi svolgono la stessa funzione.

50

Correzione disponibile.

Installare NuGet pacchetto DotNetOpenAuth.Mvc5 e cambiare tutti gli usi di AsActionResult()-AsActionResultMvc5()

+2

C'è un modo per usarlo con il pacchetto * unified *? o dobbiamo rimuoverlo e riaggiungere tutti i singoli componenti separatamente? –

+3

Ci sono conflitti quando si utilizza già il pacchetto DotNetOpenAuth.Ultimate. –

+0

Utilizzo del pacchetto DotNetOpenAuth.Ultimate. Sto ancora ricevendo quell'errore. Qualcosa cambia negli aggiornamenti? – MoXplod

2

uso questo per garantire che l'Authorizer viene passato in modo corretto.

public class MvcAuthorizer : WebAuthorizer 
{ 
    public ActionResult BeginAuthorization() 
    { 
     return new MvcOAuthActionResult(this); 
    } 

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

'quindi recuperare correttamente

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

Se utilizzarlo con OutgoingWebresponse (non aggiornare dotnetOpenAuth ma sì MVC a 5).

Aggiungere questa classe (violato dalla risposta langtu s'):

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

e quindi sostituire:

ritorno response.AsActionResult();

con

ritorno nuova WrapperHttpResponseMessageResult (risposta);

+0

Il più semplice e più pulito è installare il pacchetto nuget DotNetOpenAuth.Mvc5 come Andrew Arnott menzionato di seguito. – decocijo