【问题标题】:DotNetOpenAuth not working with MVC 5 RCDotNetOpenAuth 不适用于 MVC 5 RC
【发布时间】:2013-10-01 13:08:16
【问题描述】:

我一直在使用 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.MessagingMessagingUtilities 静态类的方法。 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”失败。

【问题讨论】:

    标签: c# asp.net asp.net-mvc oauth-2.0 dotnetopenauth


    【解决方案1】:

    修复可用。

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

    【讨论】:

    • 有没有办法将它与 unified 包一起使用?还是我们需要删除它并单独添加所有单独的组件?
    • 已经在使用 DotNetOpenAuth.Ultimate 包时存在冲突。
    • 使用 DotNetOpenAuth.Ultimate 包。我仍然收到该错误。更新有什么变化吗?
    【解决方案2】:

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

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

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

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

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

    【讨论】:

    • 我刚刚升级到 MVC5 并遇到了这个问题。环顾四周,我惊讶地发现 AA 放弃了这个项目。我真的不知道 DNOA 是否仍在积极开发中,因为很长时间没有发布。项目状态如何?你还在使用 DNOA 吗?
    【解决方案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 复制而来的,所以它们的功能相同。

    【讨论】:

      【解决方案4】:

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

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

      【讨论】:

        【解决方案5】:

        如果将其与 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();

        return new WrapperHttpResponseMessageResult(response);

        【讨论】:

        • 最简单和最干净的方法是安装下面提到的 Andrew Arnott 的 DotNetOpenAuth.Mvc5 nuget 包。
        猜你喜欢
        • 1970-01-01
        • 2022-01-18
        • 2017-01-12
        • 2014-11-26
        • 2015-08-15
        • 2015-10-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多