【发布时间】:2017-12-23 02:49:20
【问题描述】:
当我在 owin OAUth 旁边使用 Simpleinjector 进行基于令牌的登录时,Simpleinjector 无法解析我的控制器,并且出现“找不到资源”消息的 404 错误。
我使用 owin 管道处理我的请求,并使用 Owin Security 来生成和验证用户令牌。
Simpleinjector 作为 DI 和 ASP.NET 5
我在 stackoverflow 上试过这个解决方案: UserManager dependency injection with Owin and Simple Injector
这个在 simpleinjector 文档中: http://simpleinjector.readthedocs.io/en/latest/owinintegration.html
这对我不起作用(我没有BeginExecutionContextScope)
WebApi + Simple Injector + OWIN
这是我的 startup.cs:
public class Startup
{
public void Configuration(IAppBuilder app)
{
SimpleInjectorBootstrapper.Initialize();
app.Use(async (context, next) => {
using (AsyncScopedLifestyle.BeginScope(SharedLayer.Core.CoreObject.container))
{
await next();
}
});
ConfigureOAuth(app);
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
FilterConfig.RegisterHttpFilters(GlobalConfiguration.Configuration.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
HttpConfiguration config = new HttpConfiguration();
WebApiConfig.Register(config);
DependencyResolver.SetResolver(new SimpleInjectorDependencyResolver(SharedLayer.Core.CoreObject.container));
config.DependencyResolver = new SimpleInjectorWebApiDependencyResolver(SharedLayer.Core.CoreObject.container);
app.Use<ExceptionMiddleware>();
app.Map(new PathString("/api"), application => { application.Use<AuthenticateMiddleware>(); });
app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);
app.UseWebApi(config);
}
public void ConfigureOAuth(IAppBuilder app)
{
OAuthAuthorizationServerOptions OAuthServerOptions = new OAuthAuthorizationServerOptions()
{
AllowInsecureHttp = true,
TokenEndpointPath = new PathString("/token"),
AccessTokenExpireTimeSpan = TimeSpan.FromMinutes(30),
Provider = new AuthorizationProvider(),
};
app.UseOAuthAuthorizationServer(OAuthServerOptions);
app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions());
}
}
这是我的 simpleinjector 引导程序:
public static class SimpleInjectorBootstrapper
{
public static void Initialize()
{
// Create a new Simple Injector container
var container = new Container();
// Set default Scope
container.Options.DefaultScopedLifestyle = new AsyncScopedLifestyle();
// Configure the container (register)
var businessAssembly = typeof(BusinessLayer.Bootstrap.SimpleInjectorBootstrapper).Assembly;
// get services based on conditions
var registerations = from type in businessAssembly.GetExportedTypes()
where type.Namespace.Contains("BusinessLayer.Logic")
where type.GetInterfaces().Any()
select new
{
Service = type.GetInterfaces().First(),
Implementation = type
};
// register each service
foreach (var reg in registerations)
{
container.Register(reg.Service, reg.Implementation, Lifestyle.Scoped);
}
// init nested bootstrapper
BusinessLayer.Bootstrap.SimpleInjectorBootstrapper.Initialize(container);
// Register Root services
container.RegisterMvcControllers(Assembly.GetExecutingAssembly());
container.RegisterMvcIntegratedFilterProvider();
container.RegisterWebApiControllers(GlobalConfiguration.Configuration);
// Optionally verify the container's configuration.
container.Verify();
// Store the container for use by the application
//DependencyResolver.SetResolver(new SimpleInjectorDependencyResolver(container));
// Assign SimpleInjectorWebApiDependencyResolver to DependencyResolver
//GlobalConfiguration.Configuration.DependencyResolver = new SimpleInjectorWebApiDependencyResolver(container);
// store container in a static variable for DI in class libraries
SharedLayer.Core.CoreObject.container = container;
}
}
当我评论这两行时,我的应用程序运行良好:
ConfigureOAuth(app);
app.Map(new PathString("/api"), application => { application.Use<AuthenticateMiddleware>(); });
我的错误在哪里?
编辑:
我发现当我评论这一行时,我的项目运行良好:
app.Map(new PathString("/api"), application => {
application.Use<AuthenticateMiddleware>();
});
这是我的 AuthenticateMiddleware 代码:
public class AuthenticateMiddleware : OwinMiddleware
{
public AuthenticateMiddleware(OwinMiddleware next)
: base(next)
{}
public async override Task Invoke(IOwinContext context)
{
string username = "";
if (context.Request.Method.Equals(HttpMethod.Get.Method))
{
if (context.Request.Query.Any(e => e.Key == "username" && e.Value != null))
username = context.Request.Query.Get("username");
}
else
{
var body = new StreamReader(context.Request.Body).ReadToEndAsync().Result;
var dict = HttpUtility.ParseQueryString(body);
var json = new JavaScriptSerializer().Serialize(dict.AllKeys.Where(e => e.Equals("username")).ToDictionary(k => k, k => dict[k]));
JObject jsonObject = JsonConvert.DeserializeObject<JObject>(json);
username = jsonObject["username"] != null ? jsonObject["username"].ToString() : "";
}
if (username == "")
throw new ArgumentNullException("username is required.");
if (!context.Authentication.User.HasClaim("username", username))
throw new SecurityException("token is invalid.");
await Next.Invoke(context);
}
}
【问题讨论】:
-
那么例外是什么? Simple Injector 总是会抛出异常,并带有非常清晰的异常消息。如果没有此消息,我们很难为您提供帮助。
-
@Steven,很遗憾,Simpleinjector 没有异常,它只是返回 找不到资源
-
总是有一个例外。在 Visual Studio 中设置断点,或在 Visual Studio 中设置“所有异常中断”,或将异常记录到磁盘。一定有例外。
-
@Steven 相信我,我的项目中没有异常 :(( - 在所有方法结束后刚刚显示的错误页面,我可以将我的项目发送给您,它完全是空的,我没有知道我错过了什么:(
-
@Steven,我又开始了,我发现问题出在映射上
标签: asp.net asp.net-web-api owin