public class AuthorizationServerProvider : OAuthAuthorizationServerProvider { private IUserService _userService; public AuthorizationServerProvider(IUserService userService) { _userService = userService; } } public class RefreshTokenProvider : IAuthenticationTokenProvider { private IUserService _userService; public RefreshTokenProvider(IUserService userService) { _userService = userService; }
在startup.cs类中,我需要使用上面的两个类,但是当然我不能在启动类中使用构造函数注入,因为在Ninject之前初始化它.@H_403_5@
这是一个什么办法,以便引用_tokenProvider和
_AuthServerProvider在ConfigureAuth方法?@H_403_5@
public class Startup { private AuthorizationServerProvider _authServerProvider; private RefreshTokenProvider _tokenProvider; public static OAuthBearerAuthenticationOptions OAuthBearerOptions { get; private set; } public void Configuration(IAppBuilder app) { var config = new HttpConfiguration(); app.UseNinjectMiddleware(CreateKernel); app.UseNinjectWebApi(config); ConfigureOAuth(app); WebApiConfig.Register(config); app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll); app.UseWebApi(config); } public void ConfigureOAuth(IAppBuilder app) { var oAuthServerOptions = new OAuthAuthorizationServerOptions() { AllowInsecureHttp = true,//TODO: HTTPS TokenEndpointPath = new PathString("/token"),AccessTokenExpireTimeSpan = TimeSpan.FromMinutes(30),Provider = _authServerProvider,RefreshTokenProvider = _tokenProvider }; }
private static IKernel CreateKernel() { var kernel = new StandardKernel(); try { kernel.Bind<Func<IKernel>>().ToMethod(ctx => () => new Bootstrapper().Kernel); kernel.Bind<IHttpModule>().To<HttpApplicationInitializationHttpModule>(); RegisterServices(kernel); return kernel; } catch { kernel.Dispose(); throw; } }
private static void RegisterServices(IKernel kernel) { kernel.Bind<SimpleAuthorizationServerProvider>().ToSelf(); kernel.Bind<SimpleRefreshTokenProvider>().ToSelf(); }
解决方法
首先,您应该在Startup.Auth.cs中进行配置.另外,你有一些冗余.. app.UseNinjectWebApi(config)将调用app.UseWebApi(config)(见the source).我也不知道你为什么要调用WebApiConfig.Register(),因为通常在Global.asax.cs中调用@H_403_5@
无论如何,它应该是这样的(我没有测试过,但应该是接近):@H_403_5@
首先,我们将把你的内核创建移到一个懒惰的方法,然后在Startup.Configuration()方法中使用你的UseNinjectMiddleware()调用将Startup类中的lazy kerel作为成员.这最适合我作为一个简单的lambda委托,而不是创建一个静态的CreateKernel方法.@H_403_5@
public partial class Startup { private readonly Lazy<IKernel> _kernel = new Lazy<IKernel>(() => { var kernel = new StandardKernel(); kernel.Load(Assembly.GetExecutingAssembly()); // here for brevity,move this to a RegisterServices or similar method,// kernel.Bind<IOAuthAuthorizationServerOptions>() .To<MyOAuthAuthorizationServerOptions>(); kernel.Bind<IOAuthAuthorizationServerProvider>() .To<AuthorizationServerProvider>(); kernel.Bind<IAuthenticationTokenProvider>().To<RefreshTokenProvider>(); kernel.Bind<IUserService>().To<MyUserService>(); return kernel; }); public void Configuration(IAppBuilder app) { app.UseNinjectMiddleware(() => _kernel.Value); var config = new HttpConfiguration(); app.UseNinjectWebApi(config); ConfigureAuth(app); } }
然后在你的ConfigureAuth()@H_403_5@
public void ConfigureAuth(IAppBuilder app) { // .... other auth code // Yes,boo hiss,service location,not much choice... // Setup Authorization Server app.USEOAuthAuthorizationServer(_kernel.Value .Get<MyOAuthAuthorizationServerOptions>().GetOptions()); }
然后创建一个界面:@H_403_5@
public interface IOAuthAuthorizationServerOptions { OAuthAuthorizationServerOptions GetOptions(); };
创建您的实现:@H_403_5@
public class MyOAuthAuthorizationServerOptions : IOAuthAuthorizationServerOptions { private IOAuthAuthorizationServerProvider _provider; private IAuthenticationTokenProvider _tokenProvider; public MyOAuthAuthorizationServerOptions(IAuthenticationTokenProvider tProvider,IOAuthAuthorizationServerProvider provider) { _provider = provider; _tokenProvider = tProvider; } public OAuthAuthorizationServerOptions GetOptions() { return new OAuthAuthorizationServerOptions() { AllowInsecureHttp = true,//TODO: HTTPS TokenEndpointPath = new PathString("/token"),Provider = _provider,RefreshTokenProvider = _tokenProvider }; } }
编辑(4/6/15):@H_403_5@
经过进一步的思考,我认为懒惰< T>添加一个真正不必要的附加参考.这可以通过更清晰的方式进行修改,以达到相同的效果:@H_403_5@
创建一个新的Startup.Ninject.cs类,并将其放在App_Start中:@H_403_5@
public partial class Startup { public IKernel ConfigureNinject(IAppBuilder app) { var config = new HttpConfiguration(); var kernel = CreateKernel(); app.UseNinjectMiddleware(() => kernel) .UseNinjectWebApi(config); return kernel; } public IKernel CreateKernel() { var kernel = new StandardKernel(); kernel.Load(Assembly.GetExecutingAssembly()); return kernel; } } public class NinjectConfig : NinjectModule { public override void Load() { RegisterServices(); } private void RegisterServices() { kernel.Bind<IOAuthAuthorizationServerOptions>() .To<MyOAuthAuthorizationServerOptions>(); kernel.Bind<IOAuthAuthorizationServerProvider>() .To<AuthorizationServerProvider>(); kernel.Bind<IAuthenticationTokenProvider>().To<RefreshTokenProvider>(); kernel.Bind<IUserService>().To<MyUserService>(); } }
然后,在启动中这样做:@H_403_5@
public partial class Startup { public void Configuration(IAppBuilder app) { var kernel = ConfigureNinject(app); ConfigureAuth(app,kernel); } }
最后,修改ConfigureAuth以取代第二个参数.@H_403_5@
public void ConfigureAuth(IAppBuilder app,IKernel kernel) { // .... other auth code // Yes,not much choice... // Setup Authorization Server app.USEOAuthAuthorizationServer( kernel.Get<MyOAuthAuthorizationServerOptions>().GetOptions()); }