web-dev-qa-db-ja.com

DotNetOpenAuthがMVC5RCで機能しない

私はDotNetOpenAuthでたくさん働いています。最初は5.0.0-alpha1を使用しましたが、問題の原因が見つからなかったため、v4.0.30319に切り替えました。

Visual Studio2013のMVC5RCを使用して.NET4.5.1 RCでC#WebAPIプロジェクトを構築しています。IAuthorizationServerHostINonceStore、および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エラーが発生します。

誰かがこれを簡単に修正できる(または修正できない)方法について何か考えがありますか?

DotNetOpenAuthNugetパッケージが5.0のパッケージを上書きしていることに気づきませんでした。したがって、パッケージを再インストールして、assemblyBindingを再度追加した後:

_<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」へのアクセスに失敗しました。

37
jens

利用可能な修正。

NuGetパッケージDotNetOpenAuth.Mvc5をインストールし、AsActionResult()のすべての使用法をAsActionResultMvc5()に変更します。

50
Andrew Arnott

さらにデバッグし、GitHubのDotNetOpenAuthの人々と話し合った後、 https://github.com/DotNetOpenAuth/DotNetOpenAuth/issues/307 結論は、MVC5に新しいセキュリティモデルがあるということです。

したがって、リダイレクトをバインドするだけでは不十分です。さらに進むまで、2つの選択肢があります。

1)DotNetOpenAuthソースコードを取得し、すべてのプロジェクトから[Assembly:AllowPartiallyTrustedCallers]を削除します。メンバーを再コンパイルして、厳密な名前の検証を無効にしますsn -Vr *。このコードの後は、MediumTrust環境では実行できません。

2)DotNetOpenAuthソースコードを取得し、MVC5に対して再コンパイルします。

GitHubでの議論によると、将来の最善の解決策は、関連するすべてのMVCのものを別のアセンブリに移動することです。

6
jens

この場合の回避策(現在のベータ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からコピーされるため、同じ機能を果たします。

3
langtu

これを使用して、承認者が正しく渡されるようにします。

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

OutgoingWebresponseで使用する場合(dotnetOpenAuthをアップグレードしませんでしたが、mvc yesを5にアップグレードしました)。

このクラスを追加します( langt の応答からハッキングされました):

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

そして、置き換えます:

response.AsActionResult();を返します。

新しいWrapperHttpResponseMessageResult(response);を返します。