2017-04-04 1 views
0

사용자가 데이터베이스에 읽기를 수행하고 반환 된 값을 추가하여 로그인 할 때 사용자 정의 클레임을 추가해야합니다 (Google에서 외부 로그인). 의존성 주입을 위해 Ninject를 사용하여 컨트롤러에 내 비즈니스 계층 서비스에 대한 인터페이스를 주입합니다. 여기asp.net mvc에서 Ninject 사용하기 사용자 정의 클레임을 추가하는 GenerateUserIdentityAsync

public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser> manager) 
    { 
     // Note the authenticationType must match the one defined in CookieAuthenticationOptions.AuthenticationType 
     var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie); 
     // Add custom user claims here 

     string userId = userIdentity.GetUserId(); 

     //var _iUserBLL = (IUserBLL)System.Web.Mvc.DependencyResolver.Current.GetService(typeof(IUserBLL)); 
     //UserBO objUser = _iUserBLL.GetById(userId); 

     //userIdentity.AddClaim(new Claim("Value1", objUser.Value1)); 
     //userIdentity.AddClaim(new Claim("Value2", objUser.Value2)); 
     return userIdentity; 
    } 

을 System.Web.Mvc.DependencyResolver.Current.GetService 라인이 실패하고 충돌이 발생합니다

그래서 나는 주장을 추가 할 identityModels.cs 방법을 찾았습니다. 이것은 다른 작품과 나는 또한 내가 좋아하는 컨트롤러를 주입하기 위해 사용하는 것과 동일한 접근 시도했다 : 심지어

public class MyController : Controller 
{ 
    private readonly IUserBLL _iUserBLL; 

    public MyController (IUserBLL iUserBLL) 
    { 
     _iUserBLL = iUserBLL; 
    } 
} 

그리고 :

[Inject] 
    public IUserBLL _iUserBLL { get; set; } 

을하지만 GenerateUserIdentityAsync 방법에 사용되는 경우 _iUserBLL가 null입니다. 어떤 아이디어를 어떻게 커스텀 데이터베이스를 만들기 위해 IUserBLL을 삽입 할 수 있습니까?

좀 더 자세한 정보 -이 방법에 익숙하지 않은 사용자는 개별 사용자 계정이있는 비주얼 스튜디오 프로젝트에서 생성 된 ID 코드의 일부입니다. IdentityUser는 사전의 내부 동작에 선언

public class ApplicationUser : IdentityUser 
    { 
     private readonly IUserBLL _iUserBLL; 

     public ApplicationUser (IUserBLL iUserBLL) 
     { 
      _iUserBLL = iUserBLL; 
     } 
... 
} 

을 : 나는이 작동하지 않습니다 여기에 생성자를 시도 그래서

public class ApplicationUser : IdentityUser 
{ 
    public async Task<ClaimsIdentity> 
     GenerateUserIdentityAsync(UserManager<ApplicationUser> manager) 
    { 
     ... 
    } 
} 

:과 같이

전체 클래스입니다 identity.entityframework 클래스를 제공하고 편집 할 수없는 범위 내에서 호출되므로이 접근 방법을 혼동합니다.

회신 해 주셔서 감사합니다. 해결책을 찾았습니다. 여기 내가 끝난 코드가있다. 정적 인 'Create'메쏘드에 문제가있어서 대신 [Inject] 속성을 사용했습니다. 생성자에서 IUserBLL을 사용하도록 정적 'Create'메서드를 변경하는 방법이 있습니까? App_Start/IdentityConfig.cs에서

내 NinjectWebCommon.cs에서

// Configure the application sign-in manager which is used in this application. 
    public class ApplicationSignInManager : SignInManager<ApplicationUser, string> 
    { 
     [Inject] 
     public IUserBLL _iUserBLL { get; set; } 

     public ApplicationSignInManager(ApplicationUserManager userManager, IAuthenticationManager authenticationManager) 
      : base(userManager, authenticationManager) 
     { 
     } 

     public override Task<ClaimsIdentity> CreateUserIdentityAsync(ApplicationUser user) 
     { 

      var userIdentity = user.GenerateUserIdentityAsync((ApplicationUserManager)UserManager); 

      UserBO objUser = _iUserBLL.GetById(user.Id); 

      userIdentity.Result.AddClaim(new Claim("Claim1", objUser.Value1)); 
      userIdentity.Result.AddClaim(new Claim("Claim2", objUser.Value2)); 

      return userIdentity; 

     } 

     public static ApplicationSignInManager Create(IdentityFactoryOptions<ApplicationSignInManager> options, IOwinContext context) 
     { 
      return new ApplicationSignInManager(context.GetUserManager<ApplicationUserManager>(), context.Authentication); 
     } 
    } 

나는 또한 내 모든 바인딩에 여분이 라인과 같습니다 :

private static void RegisterServices(IKernel kernel) 
     { 
kernel.Bind<System.Security.Principal.IPrincipal>().ToMethod(context => HttpContext.Current.User).InRequestScope(); 
      kernel.Bind<ApplicationUserManager>().ToMethod(context => HttpContext.Current.GetOwinContext().GetUserManager<ApplicationUserManager>()).InRequestScope(); 
      kernel.Bind<ApplicationSignInManager>().ToMethod((context) => 
      { 
       var cbase = new HttpContextWrapper(HttpContext.Current); 
       return cbase.GetOwinContext().Get<ApplicationSignInManager>(); 
      }); 
... 
} 
+0

을 성공적으로 문제의 인터페이스를 주입 할 수있는 방법이 곳에서 호출되는 경우에, 당신이 당신을 포함한 클래스에 IUserBLL에 대한 생성자 주입을하지 왜 메서드 매개 변수 – Nkosi

+0

로 전달 GenerateUserIdentityAsync 메서드는 생성자에서와 동일합니까? –

+0

건배, 나는 조금 더 많은 정보를 추가했다. 이상적으로'public class ApplicationUser : IdentityUser를 가지고 싶습니다. { [Inject] public IUserBLL _iUserBLL {get; 세트; }' 그러나 _iUserBLL은 항상 null입니다. 내가 NinjectWebCommon.cs에서 뭔가를 놓치고 Ninject가 이것을 주입하라고 말합니까? – Bluemoon

답변

0

을 여기에 내가 작업 한 코드는 ApplicationUser은 엔티티 개체이며 이러한 종류의 개체는 논리를 수행하지 않는 데이터를 보유합니다. 사용자가 이 아닌 UserManager에 사용자 지정 클레임을 추가하면 훨씬 더 좋습니다. 이것을 고려하십시오 :

public class ApplicationUserManager: UserManager<ApplicationUser> 
{ 
    private readonly IUserBLL _iUserBLL; 

    public ApplicationSignInManager(IUserStore<ApplicationUser> store, 
     IUserBLL iUserBLL) 
     : base(store) 
    { 
     // if you already fully integrated Identity with ninject, 
     // ninject could automatically resolve this for you. 
     _iUserBLL=iUserBLL; 
     // other configurations here 
    } 

    public override async Task<ClaimsIdentity> CreateIdentityAsync(
     ApplicationUser user, 
     string authenticationType)   
    { 
     var userIdentity=await base.CreateIdentityAsync(user, authenticationType); 
     UserBO objUser = _iUserBLL.GetById(userId); 

     userIdentity.AddClaim(new Claim("Value1", objUser.Value1)); 
     userIdentity.AddClaim(new Claim("Value2", objUser.Value2)); 

     return userIdentity; 
    } 
} 
+0

감사 샘,이 나를 위해 일한, 나는 결국 함께 코드를 게시했습니다. 정적 인 메소드를 사용하기 때문에 [인젝션]을 사용해야했습니다. – Bluemoon

+0

Owin 컨텍스트에 등록 할 때'ApplicationSignInManager'가 필요하지 않기 때문에. ninject가 Owin 컨텍스트 대신에'ApplicationSignInManager'를 초기화하고'Startup.Auth.cs' 파일에서 등록을 제거하게함으로써 정적 메소드를 없앨 수 있습니다. –

+0

로그인 할 때 IdentityConfig 메서드의 변경 사항이 작동했지만 IdentityModels 메서드는 Startup.Auth에서 ID를 다시 생성하기 위해 호출되므로 IdentityModels 메서드를 호출하면 사용자 이름이 손실됩니다. 그래서 저는 정사각형으로 돌아가서 ApplicationUser 메소드에 IdentityModels.cs, GenerateUserIdentityAsync에서 IUserBLL을 사용하는 방법을 주입하는 방법을 모릅니다. – Bluemoon

관련 문제