在Asp.Net WebApi 項目中使用OWIN模塊之后,如果沒有在OWIN的Startup類中配置認證方式,調用WebApi的相關Controller和Action就會出現如下異常:
出現錯誤。 沒有 OWIN 身份驗證管理器與此請求相關聯。 ExceptionType:System.InvalidOperationException StackTrace: 在 System.Web.Http.Owin.PassiveAuthenticationMessageHandler.SuppressDefaultAuthenticationChallenges(HttpRequestMessage request) 在 System.Web.Http.Owin.PassiveAuthenticationMessageHandler.<SendAsync>d__0.MoveNext() --- 引發異常的上一位置中堆棧跟蹤的末尾 --- 在 System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) 在 System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) 在 System.Web.Http.HttpServer.<SendAsync>d__0.MoveNext()
如果是英文版的VisualStudio,以上異常信息會是:No OWIN authentication manager is associated with the request
原因是因為我們在Asp.Net WebApi項目使用了OWIN框架,但是沒有指定OWIN框架使用的認證方式,而WebApi也禁用了默認的身份認證,所以到來的Http請求無法進行任何身份認證(意思就是匿名訪問都不允許),拋出了異常。
我們可以看到下面的OWIN框架Startup類的Configuration方法為空,沒有為OWIN指定身份認證方式。
using System; using System.Collections.Generic; using System.Linq; using Microsoft.Owin; using Microsoft.Owin.Security; using Microsoft.Owin.Security.Cookies; using Owin; [assembly: OwinStartup(typeof(Daimler.CdnMgmt.Web.Startup))] namespace Daimler.CdnMgmt.Web { public partial class Startup { public void Configuration(IAppBuilder app) { } } }
解決方法有兩個:
第一:在OWIN的Startup類中指定默認的認證方式,我們將上面的Startup類代碼改為下面的代碼,在Configuration方法中為指定認證方式為Cookie認證。
using System; using System.Collections.Generic; using System.Linq; using Microsoft.Owin; using Microsoft.Owin.Security; using Microsoft.Owin.Security.Cookies; using Owin; [assembly: OwinStartup(typeof(Daimler.CdnMgmt.Web.Startup))] namespace Daimler.CdnMgmt.Web { public partial class Startup { public void Configuration(IAppBuilder app) { app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType); app.UseCookieAuthentication(new CookieAuthenticationOptions()); } } }
這樣調用WebApi的相關Controller和Action就不會再拋出異常了。
第二:在Asp.Net WebApi的全局配置文件WebApiConfig.cs中取消調用SuppressDefaultHostAuthentication方法,來啟用Host的默認身份認證,如下代碼所示。當然如果項目中本來就沒有代碼調用SuppressDefaultHostAuthentication方法,就不用考慮這個解決方法了。
using System; using System.Collections.Generic; using System.Linq; using System.Net.Http; using System.Web.Http; using System.Web.Http.Cors; using Daimler.CdnMgmt.Web.Utils; using Microsoft.Owin.Security.OAuth; using Newtonsoft.Json.Serialization; namespace Daimler.CdnMgmt.Web { public static class WebApiConfig { public static void Register(HttpConfiguration config) { //config.SuppressDefaultHostAuthentication();//取消調用SuppressDefaultHostAuthentication方法,恢復Host的默認身份認證 // Web API 路由 config.MapHttpAttributeRoutes(); config.Routes.MapHttpRoute( name: "DefaultApi", routeTemplate: "api/{controller}/{id}", defaults: new {id = RouteParameter.Optional} ); } } }
當然如果你的ASP.NET項目中沒有安裝或者丟失了NuGet包:Microsoft.Owin.Host.SystemWeb,但是又使用了OWIN框架,也會出現本文所述的錯誤,只要重新安裝NuGet包:Microsoft.Owin.Host.SystemWeb即可。