2017-11-05 14 views
0

これは本当に混乱しているとわかりました。私はアイデンティティサーバーへの移動に迷惑を掛けていなかったのですが、私が持っていたすべての問題が何であるかは... とにかく、現在の問題は私が認証すると、クレームはUser.Identityに基づいていません。参照トークンを使用しているときにIdentityServerが表示されるようになる

私はClaimsTransformerを使用してbut it turns out that you can't use DI to get database claims、私の主張を追加するClaimsTransformerを使用しようとしました。だから私は別の解決策を考えなければならなかった。

私は多くの掘削の後、あなたが使用できるClaimsProviderが見つかりました。しかし、私がそれを追加すると、私は私の要求を認めることができません。 は、これは私がClaimsProviderを追加前に私の設定です:

それは次のように設定して、私は私のStartup.csでそれを呼び出すされ
public static class Config 
{ 
    /// <summary> 
    ///  Configures identity server 
    /// </summary> 
    public static void ConfigureIdentityServer(this IAppBuilder app, CormarConfig config) 
    { 
     // Create our options 
     var identityServerOptions = new IdentityServerOptions 
     { 
      SiteName = "Cormar API", 
      SigningCertificate = LoadCertificate(), 
      IssuerUri = "https://cormarapi-test.azurewebsites.net", 

      LoggingOptions = new LoggingOptions 
      { 
       EnableHttpLogging = true, 
       EnableWebApiDiagnostics = true, 
       EnableKatanaLogging = true, 
       WebApiDiagnosticsIsVerbose = true 
      }, 

      Factory = new IdentityServerServiceFactory().Configure(config), 

      // Disable when live 
      EnableWelcomePage = true 
     }; 

     // Setup our auth path 
     app.Map("/identity", idsrvApp => { idsrvApp.UseIdentityServer(identityServerOptions); }); 
    } 


    /// <summary> 
    ///  Configures the identity server to use token authentication 
    /// </summary> 
    public static void ConfigureIdentityServerTokenAuthentication(this IAppBuilder app, HttpConfiguration config) 
    { 
     app.UseIdentityServerBearerTokenAuthentication(new IdentityServerBearerTokenAuthenticationOptions 
     { 
      Authority = "https://cormarapi-test.azurewebsites.net/identity", 
      DelayLoadMetadata = true, 
      ValidationMode = ValidationMode.Both, 
      RequiredScopes = new[] {"api"}, 

      ClientId = "api", 
      ClientSecret = "8at?7nAtaB!E" 
     }); 
    } 

    /// <summary> 
    ///  Loads the certificate 
    /// </summary> 
    /// <returns></returns> 
    private static X509Certificate2 LoadCertificate() 
    { 
     var certPath = $"{AppDomain.CurrentDomain.BaseDirectory}App_Data\\idsrv3test.pfx"; 
     var certStore = new X509Store(StoreName.My, StoreLocation.CurrentUser); 
     certStore.Open(OpenFlags.ReadOnly); 
     var certCollection = certStore.Certificates.Find(X509FindType.FindByThumbprint, "3A1AFB6E1DC5C3F341E63651542C740DA4148866", false); 
     certStore.Close(); 

     // If we are on azure, get the actual self signed certificate, otherwise return the test one 
     return certCollection.Count > 0 ? certCollection[0] : new X509Certificate2(certPath, "idsrv3test"); 
    } 

    /// <summary> 
    ///  Configure the identity service factory with custom services 
    /// </summary> 
    /// <returns></returns> 
    private static IdentityServerServiceFactory Configure(this IdentityServerServiceFactory factory, CormarConfig config) 
    { 
     var serviceOptions = new EntityFrameworkServiceOptions {ConnectionString = config.SqlConnectionString}; 
     factory.RegisterOperationalServices(serviceOptions); 
     factory.RegisterConfigurationServices(serviceOptions); 
     factory.CorsPolicyService = new Registration<ICorsPolicyService>(new DefaultCorsPolicyService {AllowAll = true}); // Allow all domains to access authentication 

     factory.Register(new Registration<DbContext>(dr => dr.ResolveFromAutofacOwinLifetimeScope<DbContext>())); 
     factory.UserService = new Registration<IUserService>(dr => dr.ResolveFromAutofacOwinLifetimeScope<IUserService>()); 
     factory.ClientStore = new Registration<IClientStore>(dr => dr.ResolveFromAutofacOwinLifetimeScope<IClientStore>()); 
     factory.ScopeStore = new Registration<IScopeStore>(dr => dr.ResolveFromAutofacOwinLifetimeScope<IScopeStore>()); 

     return factory; 
    } 
} 

app.ConfigureIdentityServer(scope.Resolve<CormarConfig>()); 
app.ConfigureIdentityServerTokenAuthentication(config); 
app.UseWebApi(config); 

すべての作品罰金(請求項を除いて)。私は認証することができ、私は私の要求を認めることができます。 は今、私は私のUserClaimsを取得する必要があるので、私はこのように私のClaimsProviderを作成しました:

factory.ClaimsProvider = new Registration<IClaimsProvider>(dr => dr.ResolveFromAutofacOwinLifetimeScope<IClaimsProvider>()); 

:その後、私はこのように私のIdentityServerServiceFactory設定方法にこれを追加しました

public class ClaimsProvider: DefaultClaimsProvider 
{ 

    private readonly IUserStore<User> _userStore; 
    public ClaimsProvider(IUserService userService, IUserStore<User> userStore) 
     : base(userService) 
    { 
     _userStore = userStore; 
    } 

    public override async Task<IEnumerable<Claim>> GetAccessTokenClaimsAsync(ClaimsPrincipal subject, Client client, IEnumerable<Scope> scopes, ValidatedRequest request) 
    { 
     var id = subject.GetSubjectId(); 
     var user = await _userStore.FindByIdAsync(id); 

     return user.Claims.Select(ModelFactory.Create).ToList(); 
    } 
} 

ClaimsProviderに登録されています。

のようなAutofac
builder.RegisterType<ClaimsProvider>().As<idsrv.IClaimsProvider>().InstancePerDependency(); 

私はまだ認証し、自分のトークンを取得、しかし、すぐに私は私のトークンを使用して任意のエンドポイントにアクセスしようとして、私はこのエラーを取得することができます:

invalid bearer token received

私がなぜ分かりません。誰も助けることができますか?

答えて

0

私は完全に間違った場所を探していました。 クレームをユーザーに追加するには、GetProfileDataAsyncをカスタムUserServiceに上書きする必要があります。私は前にそれをしていたが、主張は持続されていなかった。それから私はScopeClaimsについて読んだ。私の場合、私のクレームはタイプ "ロール"でしたので、私はちょうど新しいScopeClaimをロールの名前で追加し、ログインしたときにはGetProfileDataAsyncが呼び出され、私のUser.Identityに追加されました。

public override async Task GetProfileDataAsync(ProfileDataRequestContext context) 
    { 
     var subject = context.Subject; 
     var requestedClaimTypes = context.RequestedClaimTypes; 

     var user = await _userProvider.FindByIdAsync(subject.GetSubjectId()); 
     if (user == null) throw new ArgumentException("Invalid user id"); 

     var claims = GetClaimsFromUser(user); 
     if (requestedClaimTypes != null && requestedClaimTypes.Any()) claims = claims.Where(m => requestedClaimTypes.Contains(m.Type)); 

     context.IssuedClaims = claims; 
    } 

    private IEnumerable<Claim> GetClaimsFromUser(User model) 
    { 
     var claims = model.Claims.Select(ModelFactory.Create).ToList(); 

     if (model.EmailConfirmed) claims.Add(new Claim(Constants.ClaimTypes.EmailVerified, model.EmailConfirmed ? "true": "false")); 

     return claims; 
    } 
: 例として、ここに私の GetProfileDataAsyncは、次のようになります
関連する問題