私はDotNetOpenAuthでたくさん働いています。最初は5.0.0-alpha1を使用しましたが、問題の原因が見つからなかったため、v4.0.30319に切り替えました。
Visual Studio2013のMVC5RCを使用して.NET4.5.1 RCでC#WebAPIプロジェクトを構築しています。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エラーが発生します。
誰かがこれを簡単に修正できる(または修正できない)方法について何か考えがありますか?
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」へのアクセスに失敗しました。
利用可能な修正。
NuGetパッケージDotNetOpenAuth.Mvc5をインストールし、AsActionResult()
のすべての使用法をAsActionResultMvc5()
に変更します。
さらにデバッグし、GitHubのDotNetOpenAuthの人々と話し合った後、 https://github.com/DotNetOpenAuth/DotNetOpenAuth/issues/307 結論は、MVC5に新しいセキュリティモデルがあるということです。
したがって、リダイレクトをバインドするだけでは不十分です。さらに進むまで、2つの選択肢があります。
1)DotNetOpenAuthソースコードを取得し、すべてのプロジェクトから[Assembly:AllowPartiallyTrustedCallers]を削除します。メンバーを再コンパイルして、厳密な名前の検証を無効にしますsn -Vr *。このコードの後は、MediumTrust環境では実行できません。
2)DotNetOpenAuthソースコードを取得し、MVC5に対して再コンパイルします。
GitHubでの議論によると、将来の最善の解決策は、関連するすべてのMVCのものを別のアセンブリに移動することです。
この場合の回避策(現在のベータ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 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);を返します。