2017-11-25 17 views
2

Oauth를 Autofac과 통합해야합니다. 하지만 뭔가 잘못되었습니다. 나는 왜 그런지 이해하지만, 어떻게 해결해야할지 모르겠다. 제 코드를 보도록하겠습니다. 내 Autofac 구성Autofac 4.0을 통해 OAuthAuthorizationServerProvider 구성

{ 
    builder.RegisterType<CustomAuthorizationServerProvider>() 
      .PropertiesAutowired() 
      .SingleInstance(); 

    builder.RegisterType<MyBusinessObj>() 
      .As<IMyBusinessObj>() 
      .InstancePerRequest() 
      .PropertiesAutowired(); 

    //IMySessionObj is a prop inside MyBusinessObj 
    builder.RegisterType<MySessionObj>() 
      .As<IMySessionObj>() 
      .InstancePerRequest() 
      .PropertiesAutowired(); 

    //IMyUnitOfWorkObjis a prop inside MyBusinessObj 
    builder.RegisterType<MyUnitOfWorkObj>() 
      .As<IMyUnitOfWorkObj>() 
      .InstancePerRequest(); 

    ... 
} 

Startup.cs

나는 당신이 볼 수 있듯이, 나는 용기에 해결 고전적인 구성 플러스 내 authorizationServerProvider ..의 해상도를 가지고있다. .. 왜냐하면 그것은 싱글 톤이기 때문입니다. 내 CustomAuthorizationServerProvider을 구현하는 방법이있다

app.UseAutofacMiddleware(_container); 
app.UseAutofacWebApi(config); 

var oauthServerOptions = new OAuthAuthorizationServerOptions 
{ 
    ..., 
    Provider = _container.Resolve<CustomAuthorizationServerProvider>() 
}; 

app.UseOAuthAuthorizationServer(oauthServerOptions); 

app.UseWebApi(config); 

CustomAuthorizationServerProvider.cs

. 여기

public class CustomAuthorizationServerProvider: OAuthAuthorizationServerProvider 
{ 
    public override Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context) 
    { 
     var autofacLifetimeScope = OwinContextExtensions.GetAutofacLifetimeScope(context.OwinContext); 
     var myBusinessObj = autofacLifetimeScope.Resolve<IMyBusinessObj>(); 
     var xxx = myBusinessObj.DoWork(); 
     ... 
     return Task.FromResult<object>(null); 
    } 

    public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context) 
    { 
     var myBusinessObj = autofacLifetimeScope.Resolve<IMyBusinessObj>(); 
     var xxx = myBusinessObj.DoWork(); 
     ... 
     context.Validated(ticket); 
    } 
} 

내가 해결 내 IMyBusinessObj lifetimescope에서가 아닌 컨테이너에 있습니다. 이 객체는 db에 연결하고, 세션에 액세스하고, 캐시에 액세스하는 등의 책임을 (간접적으로)합니다. 그래서 싱글 톤이 될 수 없습니다.

요청 당 유효 기간이 필요합니다. 그래서 여기에 문제가 .. 두 가지 문제가 내 구성에 있습니다.

  1. 은 내가 SingleInstance 객체 내부 InstancePerRequest 개체가 있습니다. 그렇게 할수 없어. Troubleshooting Per-Request Dependencies

  2. 시작시 oauth를 구성 할 때 실제로 컨텍스트에 요청이 존재하지 않기 때문에 InstancePerRequest 개체를 가질 수 없습니다.

그래서 .. 내 문제가 무엇인지 이해했습니다.

아이디어 또는 도움말? 고맙습니다.

답변

1

동일한 문제가 아니라면 매우 비슷한 문제가있었습니다. 다음을 수행하여 문제를 해결할 수있었습니다.

IOAuthAuthorizationServerProvider을 컨테이너에서 직접 해결하지 마십시오. 대신 IDependencyResolver을 사용하십시오. 당신의 예에서 :

var oauthServerOptions = new OAuthAuthorizationServerOptions 
{ 
    ..., 
    Provider = (IOAuthAuthorizationServerProvider)resolver.GetService(typeof(IOAuthAuthorizationServerProvider)), 
}; 

이 올바르게 HttpConfiguration.DependencyResolver를 구성해야합니다 :

HttpConfiguration config = new HttpConfiguration(); 

... // Configure unrelated 

var builder = new ContainerBuilder();  

... // set Autofac registrations 

var container = builder.Build(); 

config.DependencyResolver = new AutofacWebApiDependencyResolver(container); 

// THIS is where you configure OAuthAuthorizationServerOptions, using IDependencyResolver to resolve IOAuthorizationServerProvider instead of IContainer 
ConfigureAuth(app, config.DependencyResolver); 

2 내가 특정 Autofac 모듈 등록을 구성하는 동적 조립 스캔을 사용하고 있었다. 나는 실수로 "Provider"로 끝나는 클래스를 스캔하여 RequestPerInstance()으로 등록했습니다. 이는 IOAuthAuthorizationServerProvider을 요청 당 인스턴스로 다시 등록 했으므로 Startup() 코드 중에 해결할 수없는 문제였습니다.나는 개별 등록으로 대체

문제 코드 :

builder.RegisterAssemblyTypes(executingAssembly) 
    .Where(t => t.Name.EndsWith("Provider")) 
    .AsImplementedInterfaces() 
    .InstancePerRequest();  

3. 확인 MySessionObj의 속성 및 Autofac는 (있는 경우) 해결 무엇 종속성을 참조하십시오. 종속성을 명시 적으로 InstancePerRequest()으로 등록했는지 확인하십시오.

OwinContextExtensions.GetAutofacLifetimeScope(context.OwinContext);을 사용하면 루트 범위가 아닌 "AutoFacWebRequest"수명 범위에 대한 종속성을 해결할 수 있습니다. 결과적으로, 내 이해는 요청이 완료된 후에 폐기되어야하며이 응용 프로그램에 향후 문제가 발생해서는 안되는이 수명 범위로 해결 된 종속성입니다.

4. 나는 특성이 CustomAuthorizationServerProvider 개체에 대한 autowire가되는 것이 아닙니다 확신하지만,이 클래스의 전체 코드 샘플을 게시되지 않은 당신을 가정, 나는 그것에서 PropertiesAutowired()을 제거하려고 할 것은 Autofac 등록 그리고 객체의 내부에 계속 가능한 경우 다른 속성을 해결하려면 OwinContextExtensions.GetAutofacLifetimeScope(context.OwinContext);을 사용하십시오.

관찰하고있는 오류 또는 오류 메시지의 구체적인 내용을 제공 할 수 있습니까?