我有一个API应用程序,可以在Visual Studio 2015调试器上完美运行;我试图在IIS上发布我的应用程序(我已通过控制面板安装了服务器打开/关闭Windows功能) .
我的应用程序有一个安全系统来检查任何请求是来自注册的用户,任何请求传递首先抛出 ApiAuthorizationFilter
,解析由Base64字符串组成的令牌,它在 Headers 中作为 Authorization 并返回具有JSON的特定 HttpStatusCode
.
部署后发生异常,如果我在IIS上的应用程序上运行测试,则会在 Filter.ApiAuthorizationFilter
处抛出 NullReferenceException
,但如果我在Visual Studio上运行相同的应用程序 - 它可以正常工作 .
这是错误消息:
500:内部服务器错误“消息”:“发生错误 . ” “ExceptionMessage”:“对象引用未设置为对象的实例 . ” “ExceptionType”:“System.NullReferenceException”“StackTrace”:“在System.Web.Http.Filters.AuthorizationFilterAttribute.OnAuthorizationAsync(HttpActionContext actionContext,CancellationToken cancellationToken)的API.CARDS.Models.Filter.ApiAuthorizationFilter.OnAuthorization(HttpActionContext actionContext)中 - - 从抛出异常的先前位置开始的堆栈跟踪结束---在System.Web.Http的System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务任务)的System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(任务任务)处.Filters.AuthorizationFilterAttribute.d__2.MoveNext()---在抛出异常的前一个位置的堆栈跟踪结束---在System.Runtime.CompilerServices.TaskAwaiter的System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(任务任务)处 . System.Web.Http.Dispatcher.HttpControllerDispatcher.d__1.MoveNext()中的HandleNonSuccessAndDebuggerNotification(任务任务)
这是代码:
ApiAuthorizationFilter
public class ApiAuthorizationFilter : AuthorizationFilterAttribute
{
[Inject]
public IEncryptionSystemService service { get; set; }
[Inject]
public IUserService userService { get; set; }
public override void OnAuthorization(HttpActionContext actionContext)
{
//Hace una petición (request) al actionContext
HttpRequestMessage request = actionContext.Request;
try
{
//Establece la cultura (Ejemplo: es-MX) para los mensajes i18n
string culture = actionContext.Request.Headers.AcceptLanguage.ToString();
if (culture.Length == 5)
{
Thread.CurrentThread.CurrentCulture = new CultureInfo(culture);
Thread.CurrentThread.CurrentUICulture = new CultureInfo(culture);
}
//Crea un token con los valores que se obtienen del actionContext, mismos que serán las credenciales para accesar.
string token = actionContext.Request.Headers.GetValues("Authorization").FirstOrDefault().Replace("Credentials", "").Trim();
//Desencripta las credenciales con el servicio del tipo IEncryptionService.
string[] userPass = service.DecryptText(token);
User model = new User { email = userPass[0], password = userPass[1] };
////Verifica que sean correctas las credenciales que ser obtuvieron del token.
AuthorizationResult result = userService.LoginUser(model);
switch (result)
{
case AuthorizationResult.ACCESS_GRANTED:
User user = new User { email = model.email };
ApiIdentity identity = new ApiIdentity(user);
ApiPrincipal principal = new ApiPrincipal(identity);
Thread.CurrentPrincipal = principal;
break;
case AuthorizationResult.ACCESS_DENIED:
actionContext.Response = request.CreateResponse(HttpStatusCode.NotFound, "ErrorResources.NotFound");
break;
case AuthorizationResult.PERMISSION_DENIED:
actionContext.Response = request.CreateResponse(HttpStatusCode.Unauthorized, "ErrorResources.Unauthorized");
break;
}
}
catch (Exception e)
{
throw;
//Si existe un error durante la petición, regresa un estatus de InternalServerError (Error interno del Servidor).
//actionContext.Response = request.CreateErrorResponse(HttpStatusCode.InternalServerError, string.Format("ErrorResources.AuthenticationError ---- {0}",e.Message));
}
}
}
1 回答
经过一番大研究后我找到了答案!这个答案适用于 API Application with NInject, Leppie是对的问题是 Dependency Injection Configuration.
首先我必须清理从 NuGet 安装的数据包,我不得不用这些数据包重新安装 Ninject .
Ninject
Ninject.web.WebApi
Ninject.web.WebApi.WebHost - 我错过了这个, this is required for IIS support
Ninject.MVC3
Ninject.web.Common
Ninject.web.Common.WebHost - 将此版本更新为最新版本(3.2.3), this is required for IIS support
之后检查你的类 NInjectWebCommon.cs ,在名为 CreateKernel() 的方法中,我有这一行
你需要删除它,因为这将抛出
如果一切都好!您的应用程序将在 IIS Server 上运行 .
这些文件是我在App_Start文件夹中的NInject的最后一个配置
NinjectWebCommon.cs
NinjectResolver.cs
NinjectScope.cs
IMPORTANT! For SQL Server Users 正如你在我的 ApiFilterConfiguration 上看到的那样我有这一行
AuthorizationResult result = userService.LoginUser(model);
这个 userService 是我用方法创建的类 LoginUser(model) 这个方法从 Request Headers 获取一个模型并转到 SQL SERVER 以验证用户是否存在 .如果你用我的默认配置安装 SQL Server ,也许你有另一个问题抛出 Null reference after a consult ,请查看这个主题 Login failed for user IIS APPPOOL\AppPool4.5 or APPPOOL\ASP.NET 也许你需要在 SQLSERVER 上为 IIS 创建一个登录名