38

我一直在使用 DotNetOpenAuth。首先,我们使用 5.0.0-alpha1,但我们切换到 v4.0.30319,因为我们找不到导致问题的原因。

我们正在 Visual Studio 2013 中使用 MVC 5 RC 在 .NET 4.5.1 RC 上构建 C# Web API 项目。我们已经实现了IAuthorizationServerHostINonceStoreICryptoKeyStore.

我们遇到的问题是围绕以下情况:

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

<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”失败。

4

5 回答 5

52

修复可用。

安装 NuGet 包 DotNetOpenAuth.Mvc5 并将所有用途更改AsActionResult()AsActionResultMvc5()

于 2013-10-20T23:01:44.480 回答
6

在进一步调试并与 GitHub https://github.com/DotNetOpenAuth/DotNetOpenAuth/issues/307的DotNetOpenAuth 人员交谈后,得出的结论是 MVC 5 具有新的安全模型。

因此,绑定重定向是不够的。直到进一步,有两种选择:

1) 获取 DotNetOpenAuth 源代码并从所有项目中删除 [assembly: AllowPartiallyTrustedCallers]。重新编译和成员以禁用强名称验证 sn -Vr *. 在此代码无法在中等信任环境中运行之后。

2) 获取 DotNetOpenAuth 源代码并针对 MVC 5 重新编译它。

根据 GitHub 上的讨论,未来最好的解决方案是将所有相关的 MVC 内容移到单独的程序集中。

于 2013-09-26T06:38:04.417 回答
3

这种情况的解决方法(可以与当前的 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,因此它们执行相同的功能。

于 2013-10-01T15:15:56.450 回答
2

使用它来确保授权人被正确传递。

  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);
    }
}
于 2013-12-12T01:51:04.933 回答
0

如果将它与 OutgoingWebresponse 一起使用(没有升级 dotnetOpenAuth 但 mvc yes 到 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();
        }
    }
}

然后替换:

返回响应.AsActionResult();

返回新的 WrapperHttpResponseMessageResult(response);

于 2014-09-26T18:55:21.563 回答