예제 #1
0
        private void InitializeIdentityServerDatabase(IApplicationBuilder app)
        {
            using (var serviceScope = app.ApplicationServices.GetService <IServiceScopeFactory>().CreateScope()) {
                serviceScope.ServiceProvider.GetRequiredService <PersistedGrantDbContext>().Database.Migrate();
                var context = serviceScope.ServiceProvider.GetRequiredService <ConfigurationDbContext>();
                context.Database.Migrate();
                if (!context.Clients.Any())
                {
                    var client1 = new IdentityServer4.Models.Client {
                        ClientId          = "demo.client1",
                        AllowedGrantTypes = GrantTypes.ClientCredentials,
                        ClientSecrets     =
                        {
                            new IdentityServer4.Models.Secret("secret".Sha256())
                        },
                        AllowedScopes = { "demo.api1" },
                        ClientName    = "Demo Client1"
                    };
                    context.Clients.Add(client1.ToEntity());
                    context.SaveChanges();
                }

                if (!context.ApiResources.Any())
                {
                    var api1 = new IdentityServer4.Models.ApiResource {
                        Name        = "demo.api1",
                        DisplayName = "demo api",
                        Description = "this is just for demo"
                    };
                    context.ApiResources.Add(api1.ToEntity());
                    context.SaveChanges();
                }
            }
        }
예제 #2
0
        public async Task StoreAsync(Model.ApiResource model)
        {
            var entity = model.ToEntity();

            try
            {
                // Remove old scope indexes
                var existingEntity = await StorageContext.GetEntityBlobAsync <Entities.ApiResource>(entity.Name, StorageContext.ApiResourceBlobContainer);

                if (existingEntity != null &&
                    existingEntity.Scopes != null &&
                    existingEntity.Scopes.Count > 0)
                {
                    //Remove old scope indexes
                    var deleteIndexes = existingEntity?.Scopes?.Select(s => s.Name).Distinct().Select(i => GenerateResourceIndexEntity(entity.Name, i)).ToList();
                    await DeleteScopeIndexesAsync(deleteIndexes, StorageContext.ApiResourceTable);
                }
                // Add new scope indexes
                var newIndexes = entity?.Scopes?.Select(s => s.Name).Distinct().Select(i => GenerateResourceIndexEntity(entity.Name, i)).ToList();
                await CreateScopeIndexesAsync(newIndexes, StorageContext.ApiResourceTable);

                await StorageContext.SaveBlobAsync(entity.Name, JsonConvert.SerializeObject(entity), StorageContext.ApiResourceBlobContainer);
            }
            catch (AggregateException agg)
            {
                ExceptionHelper.LogStorageExceptions(agg, (tblEx) =>
                {
                    _logger.LogWarning("exception updating {apiName} api resource in table storage: {error}", model.Name, tblEx.Message);
                }, (blobEx) =>
                {
                    _logger.LogWarning("exception updating {apiName} api resource in blob storage: {error}", model.Name, blobEx.Message);
                });
                throw;
            }
        }
예제 #3
0
        public void Properties_Map()
        {
            var model = new ApiResource()
            {
                Description = "description",
                DisplayName = "displayname",
                Name        = "foo",
                Scopes      = { new Scope("foo1"), new Scope("foo2") },
                Enabled     = false
            };


            var mappedEntity = model.ToEntity();

            mappedEntity.Scopes.Count.Should().Be(2);
            var foo1 = mappedEntity.Scopes.FirstOrDefault(x => x.Name == "foo1");

            foo1.Should().NotBeNull();
            var foo2 = mappedEntity.Scopes.FirstOrDefault(x => x.Name == "foo2");

            foo2.Should().NotBeNull();


            var mappedModel = mappedEntity.ToModel();

            mappedModel.Description.Should().Be("description");
            mappedModel.DisplayName.Should().Be("displayname");
            mappedModel.Enabled.Should().BeFalse();
            mappedModel.Name.Should().Be("foo");
        }
예제 #4
0
        public void Update(ApiResource obj)
        {
            var apiResource = DbSet.FirstOrDefault(w => w.Name == obj.Name);
            var newOne      = obj.ToEntity();

            newOne.Id = apiResource.Id;
            DbSet.Update(newOne);
        }
예제 #5
0
        public void TestResourceConversion()
        {
            var is4Resource = new IS4.ApiResource();
            var resource    = is4Resource.ToApiResourceViewModel();

            // Secret should never be automatically copied to view model.
            Assert.Null(resource.ApiSecret);
        }
        /// <summary>
        /// Stores a new API resource
        /// </summary>
        /// <param name="resource"></param>
        /// <returns></returns>
        public async Task StoreAsync(ApiResource resource)
        {
            await _apiResources.InsertAsync(new ApiResourceEntity(resource.Name)
            {
                Description = resource.Description,
                DisplayName = resource.DisplayName,
                Enabled     = resource.Enabled,
            });

            foreach (var claim in resource.UserClaims)
            {
                await _apiResourceClaims.InsertAsync(new ApiResourceClaimEntity
                {
                    Name  = resource.Name,
                    Claim = claim,
                });
            }

            var secrets = resource.ApiSecrets.ToArray();

            for (var index = 0; index < resource.ApiSecrets.Count; index++)
            {
                var secret = secrets[index];
                await _apiSecrets.InsertAsync(new ApiSecretEntity
                {
                    Name        = resource.Name,
                    Sequence    = index,
                    Description = secret.Description,
                    Expiration  = secret.Expiration,
                    Value       = secret.Value,
                    Type        = secret.Type,
                });
            }

            foreach (var scope in resource.Scopes)
            {
                await _byScopes.InsertAsync(new ApiResourceNameByScope { Scope = scope.Name, Name = resource.Name, });

                await _apiScopes.InsertAsync(new ApiScopeEntity
                {
                    Name                    = resource.Name,
                    Scope                   = scope.Name,
                    Description             = scope.Description,
                    DisplayName             = scope.DisplayName,
                    Required                = scope.Required,
                    ShowInDiscoveryDocument = scope.ShowInDiscoveryDocument,
                });

                foreach (var claim in scope.UserClaims)
                {
                    await _apiScopeClaims.InsertAsync(new ApiScopeClaimEntity
                    {
                        Scope = $"{resource.Name}|{scope.Name}",
                        Claim = claim,
                    });
                }
            }
        }
        public async Task StoreAsync(Model.ApiResource model)
        {
            var entity = model.ToEntity();

            try
            {
                // Remove old scope indexes
                var existingEntity = await StorageContext.GetEntityBlobAsync <Entities.ApiResource>(entity.Name, StorageContext.ApiResourceBlobContainer).ConfigureAwait(false);

                if (existingEntity != null &&
                    existingEntity.Scopes != null &&
                    existingEntity.Scopes.Count > 0)
                {
                    //Remove old scope indexes
                    var deleteIndexes = existingEntity?.Scopes?.Select(s => s.Name).Distinct().Select(i => GenerateResourceIndexEntity(entity.Name, i));
                    await DeleteScopeIndexesAsync(deleteIndexes, StorageContext.ApiResourceTable).ConfigureAwait(false);
                }
                // Add new scope indexes
                var newIndexes = entity?.Scopes?.Select(s => s.Name).Distinct().Select(i => GenerateResourceIndexEntity(entity.Name, i));
                await CreateScopeIndexesAsync(newIndexes, StorageContext.ApiResourceTable).ConfigureAwait(false);

                await StorageContext.SaveBlobWithHashedKeyAsync(entity.Name,
                                                                JsonConvert.SerializeObject(entity), StorageContext.ApiResourceBlobContainer)
                .ConfigureAwait(false);

                //Create ApiScopes that don't exist
                List <string> entityScopes = entity.Scopes?.Select(s => s.Name).ToList();
                if (entityScopes.Count > 0)
                {
                    List <Model.ApiScope> existingApiScopes = (await FindApiScopesByNameAsync(entityScopes).ConfigureAwait(false)).ToList();
                    foreach (string entityScope in entityScopes.Where(w => !String.IsNullOrEmpty(w)).Distinct())
                    {
                        if (!existingApiScopes.Any(a => entityScope.Equals(a.Name, StringComparison.Ordinal)))
                        {
                            await StoreAsync(new Model.ApiScope()
                            {
                                Name = entityScope
                            }).ConfigureAwait(false);
                        }
                    }
                }
                var entities = await GetAllApiResourceEntitiesAsync().ConfigureAwait(false);

                entities = entities.Where(e => entity.Name != e.Name).Concat(new Entities.ApiResource[] { entity });
                await UpdateApiResourceCacheFileAsync(entities).ConfigureAwait(false);
            }
            catch (AggregateException agg)
            {
                ExceptionHelper.LogStorageExceptions(agg, (tblEx) =>
                {
                    _logger.LogWarning("exception updating {apiName} api resource in table storage: {error}", model.Name, tblEx.Message);
                }, (blobEx) =>
                {
                    _logger.LogWarning("exception updating {apiName} api resource in blob storage: {error}", model.Name, blobEx.Message);
                });
                throw;
            }
        }
예제 #8
0
        public void Can_Map()
        {
            var model        = new ApiResource();
            var mappedEntity = model.ToEntity();
            var mappedModel  = mappedEntity.ToModel();

            Assert.NotNull(mappedModel);
            Assert.NotNull(mappedEntity);
        }
예제 #9
0
        public async Task <bool> AddApiResource(IdentityServer4.Models.ApiResource resource)
        {
            bool Result = false;
            await Context.ApiResources.AddAsync(resource.ToEntity());

            Result = await Context.SaveChangesAsync() > 0;

            return(Result);
        }
 private static void AddTestEntitiesToSql(IS4.Client client, IS4.ApiResource apiResource)
 {
     using (var identityContext = IdentityDbContext)
     {
         identityContext.Database.ExecuteSqlCommand(DeleteDataSql);
         identityContext.ApiResources.Add(apiResource.ToEntity());
         identityContext.Clients.Add(client.ToEntity());
         identityContext.SaveChanges();
     }
 }
예제 #11
0
        public async Task UpdateWithChildrens(string oldName, ApiResource irs)
        {
            var apiDb = await DbSet
                        .Include(s => s.UserClaims)
                        .Where(x => x.Name == oldName).FirstAsync();

            var newIr = irs.ToEntity();

            newIr.Id = apiDb.Id;
            newIr.ShallowCopyTo(apiDb);
        }
        public async Task <MessageModel <string> > SaveData(ApiResourceDto request)
        {
            if (request != null && request.Id == 0)
            {
                IdentityServer4.Models.ApiResource apiResource = new IdentityServer4.Models.ApiResource()
                {
                    Name        = request?.Name,
                    DisplayName = request?.DisplayName,
                    Description = request?.Description,
                    Enabled     = true,
                    UserClaims  = request?.UserClaims?.Split(","),
                };

                var result = (await _configurationDbContext.ApiResources.AddAsync(apiResource.ToEntity()));
                await _configurationDbContext.SaveChangesAsync();
            }

            if (request != null && request.Id > 0)
            {
                var modelEF = (await _configurationDbContext.ApiResources
                               .Include(d => d.UserClaims)
                               .ToListAsync()).FirstOrDefault(d => d.Id == request.Id);

                modelEF.Name        = request?.Name;
                modelEF.DisplayName = request?.DisplayName;
                modelEF.Description = request?.Description;

                var apiResourceClaim = new List <IdentityServer4.EntityFramework.Entities.ApiResourceClaim>();
                if (!string.IsNullOrEmpty(request?.UserClaims))
                {
                    request?.UserClaims.Split(",").Where(s => s != "" && s != null).ToList().ForEach(s =>
                    {
                        apiResourceClaim.Add(new IdentityServer4.EntityFramework.Entities.ApiResourceClaim()
                        {
                            ApiResource   = modelEF,
                            ApiResourceId = modelEF.Id,
                            Type          = s
                        });
                    });
                    modelEF.UserClaims = apiResourceClaim;
                }


                var result = (_configurationDbContext.ApiResources.Update(modelEF));
                await _configurationDbContext.SaveChangesAsync();
            }


            return(new MessageModel <string>()
            {
                success = true,
                msg = "添加成功",
            });
        }
        public async Task <IActionResult> Put(string resourceName, [FromBody] IroncladResource model)
        {
            if (string.Equals(resourceName, "auth_api", StringComparison.OrdinalIgnoreCase))
            {
                return(this.BadRequest(new { Message = $"Cannot modify the authorization console web API" }));
            }

            using (var session = this.store.LightweightSession())
            {
                var document = await session.Query <PostgresResource>().SingleOrDefaultAsync(item => item.Name == resourceName);

                if (document == null)
                {
                    return(this.NotFound(new { Message = $"API resource '{resourceName}' not found" }));
                }

                // NOTE (Cameron): Because of the mapping/conversion unknowns we rely upon the Postgres integration to perform that operation which is why we do this...
                var resource = new IdentityServerResource
                {
                    UserClaims = model.UserClaims,
                    Scopes     = model.ApiScopes.Select(scope => new Scope(scope.Name, scope.UserClaims)).ToList(),
                };

                // NOTE (Cameron): If the secret is updated we want to add the new secret...
                if (!string.IsNullOrEmpty(model.ApiSecret))
                {
                    resource.ApiSecrets = new List <Secret> {
                        new Secret(model.ApiSecret.Sha256())
                    };
                }

                var entity = resource.ToEntity();

                // update properties (everything supported is an optional update eg. if null is passed we will not update)
                document.DisplayName = model.DisplayName ?? document.DisplayName;
                document.UserClaims  = entity.UserClaims ?? document.UserClaims;
                document.Scopes      = entity.Scopes ?? document.Scopes;
                document.Enabled     = model.Enabled ?? document.Enabled;

                if (!string.IsNullOrEmpty(model.ApiSecret))
                {
                    document.Secrets.Add(entity.Secrets.First());
                }

                session.Update(document);

                await session.SaveChangesAsync();
            }

            return(this.Ok());
        }
예제 #14
0
        public static IS4.ApiResource ToIs4ApiResource(this ApiResource apiResource)
        {
            var newResource = new IS4.ApiResource
            {
                Enabled     = apiResource.Enabled,
                Name        = apiResource.Name,
                DisplayName = apiResource.DisplayName,
                Description = apiResource.Description,
                UserClaims  = new List <string>(apiResource.UserClaims),
                Scopes      = apiResource.Scopes.Select(s => s.ToIs4Scope()).ToList()
            };

            return(newResource);
        }
예제 #15
0
        public static ApiResource ToApiResourceViewModel(this IS4.ApiResource resource)
        {
            var newResource = new ApiResource
            {
                Enabled     = resource.Enabled,
                Name        = resource.Name,
                DisplayName = resource.DisplayName,
                Description = resource.Description,
                UserClaims  = new List <string>(resource.UserClaims),
                Scopes      = resource.Scopes.Select(s => s.ToScopeViewModel()).ToList()
            };

            return(newResource);
        }
        public IActionResult AddApiResource(ApiResourceViewModel apiResourceViewModel)
        {
            if (!ModelState.IsValid)
            {
                return(View());
            }

            var apiResource = new ApiResourceModel(apiResourceViewModel.Name, apiResourceViewModel.DisplayName);

            _configurationDbContext.ApiResources.Add(apiResource.ToEntity());
            _configurationDbContext.SaveChanges();

            _trackTelemetry.TrackEvent(EventName.AddApiResource, EventType.Action, EventStatus.Success);
            return(RedirectToAction(nameof(Index)));
        }
예제 #17
0
        public async void ShouldAddAndSaveTheApiResourceInTheContext()
        {
            var apiResource   = new Models.ApiResource();
            var context       = A.Fake <IConfigurationDbContext>();
            var apiRepository = new ApiResourceRepository(context);

            await apiRepository.AddAsync(apiResource);

            A.CallTo(() => context.SaveChangesAsync())
            .MustHaveHappened();

            A.CallTo(() => context.ApiResources.AddAsync(
                         A <Entities.ApiResource> .Ignored,
                         A <CancellationToken> .Ignored))
            .MustHaveHappened();
        }
        private async Task <ApiResource> ConvertToModelAsync(ApiResourceEntity entity)
        {
            var resource = new ApiResource
            {
                Enabled     = entity.Enabled,
                Name        = entity.Name,
                DisplayName = entity.DisplayName,
                Description = entity.Description,
            };

            await foreach (var claim in _apiResourceClaims.EnumAsync(entity.Name))
            {
                resource.UserClaims.Add(claim.Claim);
            }

            await foreach (var secret in _apiSecrets.EnumAsync(entity.Name))
            {
                resource.ApiSecrets.Add(new Secret
                {
                    Description = secret.Description,
                    Expiration  = secret.Expiration,
                    Type        = secret.Type,
                    Value       = secret.Value,
                });
            }

            await foreach (var scope in _apiScopes.EnumAsync(entity.Name))
            {
                var apiScope = new Scope
                {
                    Name                    = scope.Scope,
                    DisplayName             = scope.DisplayName,
                    Emphasize               = scope.Emphasize,
                    Required                = scope.Required,
                    ShowInDiscoveryDocument = scope.ShowInDiscoveryDocument,
                };

                await foreach (var claim in _apiScopeClaims.EnumAsync($"{entity.Name}|{apiScope.Name}"))
                {
                    apiScope.UserClaims.Add(claim.Claim);
                }

                resource.Scopes.Add(apiScope);
            }

            return(resource);
        }
예제 #19
0
        public Task <is4Models.ApiResource> FindApiResourceAsync(string name)
        {
            is4Models.ApiResource apiResource = new is4Models.ApiResource();

            var resourceEntity = _apiResourceService.GetSingle(i => i.Name == name);

            if (resourceEntity != null)
            {
                _logger.LogDebug("Found {api} API resource in database", name);
                apiResource = _mapper.Map <is4Models.ApiResource>(resourceEntity);
            }
            else
            {
                _logger.LogDebug("Did not find {api} API resource in database", name);
            }

            return(Task.FromResult(apiResource));
        }
        public static void SeedConfiguration(IConfigurationDbContext context)
        {
            Log.Information("Seeding Identity Server configuration");
            if (!context.Clients.Any())
            {
                context.Clients.Add(new Client
                {
                    ClientId   = "spa",
                    ClientName = "SPA Client",
                    ClientUri  = "http://localhost:4200",

                    AllowedGrantTypes           = GrantTypes.Implicit,
                    AllowAccessTokensViaBrowser = true,
                    RequireConsent = false,
                    RedirectUris   =
                    {
                        "http://localhost:4200",
                        "http://localhost:4200/auth-callback",
                        "http://localhost:4200/silent.html",
                    },
                    PostLogoutRedirectUris = { "http://localhost:4200" },
                    AllowedCorsOrigins     = { "http://localhost:4200" },
                    AllowedScopes          = { "openid", "profile", "api" }
                }.ToEntity());
                context.SaveChanges();
            }

            if (!context.IdentityResources.Any())
            {
                context.IdentityResources.AddRange(new IdentityResource[]
                {
                    new IdentityResources.OpenId(),
                    new IdentityResources.Profile()
                }.Select(r => r.ToEntity()));
                context.SaveChanges();
            }

            if (!context.ApiResources.Any())
            {
                var apiResource = new ApiResource("api", "Application api");
                context.ApiResources.Add(apiResource.ToEntity());
                context.SaveChanges();
            }
        }
        public void missing_values_should_use_defaults()
        {
            var entity = new IdentityServer4.EntityFramework.Entities.ApiResource
            {
                Secrets = new System.Collections.Generic.List <Entities.ApiResourceSecret>
                {
                    new Entities.ApiResourceSecret
                    {
                    }
                }
            };

            var def = new ApiResource
            {
                ApiSecrets = { new Models.Secret("foo") }
            };

            var model = entity.ToModel();

            model.ApiSecrets.First().Type.Should().Be(def.ApiSecrets.First().Type);
        }
        public async Task <IActionResult> Post([FromBody] IroncladResource model)
        {
            if (string.IsNullOrEmpty(model.Name))
            {
                return(this.BadRequest(new { Message = $"Cannot create an API resource without a name" }));
            }

            if (string.IsNullOrEmpty(model.ApiSecret))
            {
                return(this.BadRequest(new { Message = $"Cannot create an API resource without a secret" }));
            }

            var resource = new IdentityServerResource(model.Name, model.DisplayName)
            {
                ApiSecrets = new List <Secret> {
                    new Secret(model.ApiSecret.Sha256())
                },
            };

            // optional properties
            resource.UserClaims = model.UserClaims ?? resource.UserClaims;
            resource.Scopes     = model.ApiScopes?.Select(item => new Scope(item.Name, item.UserClaims)).ToList() ?? resource.Scopes;
            resource.Enabled    = model.Enabled ?? resource.Enabled;

            using (var session = this.store.LightweightSession())
            {
                if (session.Query <PostgresResource>().Any(document => document.Name == model.Name))
                {
                    return(this.StatusCode((int)HttpStatusCode.Conflict, new { Message = "API resource already exists" }));
                }

                session.Insert(resource.ToEntity());

                await session.SaveChangesAsync();
            }

            return(this.Created(new Uri(this.HttpContext.GetIdentityServerRelativeUrl("~/api/apiresources/" + model.Name)), null));
        }
 public RegisterApiResourceCommand(IdentityServer4.Models.ApiResource apiResource)
 {
     Resource = apiResource;
 }
 /// <summary>
 /// Maps a model to an entity.
 /// </summary>
 /// <param name="model">The model.</param>
 /// <returns></returns>
 public static Entities.ApiResource ToEntity(this Models.ApiResource model)
 {
     return(model == null ? null : Mapper.Map <Entities.ApiResource>(model));
 }
예제 #25
0
        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddControllers();

            var migrationsAssembly = typeof(Startup).GetTypeInfo().Assembly.GetName().Name;

            var api = new IdentityServer4.Models.ApiResource("WebApi", "WebApi", new List <string> {
                "hotel",
                "store",
                "user",
                "role",
                "other"
            });

            api.ApiSecrets = new List <Secret> {
                new IdentityServer4.Models.Secret("654321".Sha256())
            };

            var apis = new List <IdentityServer4.Models.ApiResource> {
                api
            };
            var clients = new List <IdentityServer4.Models.Client> {
                new IdentityServer4.Models.Client {
                    ClientId          = "hms_client",
                    AllowedGrantTypes = new List <string> {
                        "password"
                    },
                    AllowOfflineAccess          = true,
                    AccessTokenType             = AccessTokenType.Reference,
                    AccessTokenLifetime         = 86400,
                    SlidingRefreshTokenLifetime = 1296000,
                    ClientSecrets = { new IdentityServer4.Models.Secret("123456".Sha256()) },
                    AllowedScopes = new List <string> {
                        "WebApi"
                    }
                },
            };

            services.AddIdentityServer()
            .AddDeveloperSigningCredential()
            .AddInMemoryApiResources(apis)
            .AddInMemoryClients(clients)
            .AddInMemoryIdentityResources(new IdentityServer4.Models.IdentityResource[]
            {
                new IdentityServer4.Models.IdentityResources.OpenId(),
                new IdentityServer4.Models.IdentityResources.Profile()
            })
            .AddOperationalStore(opt =>
            {
                opt.ConfigureDbContext = context =>
                {
                    context.UseMySQL(Configuration.GetConnectionString("AuthDB"), sql =>
                    {
                        sql.MigrationsAssembly(migrationsAssembly);
                    });
                };
                opt.EnableTokenCleanup   = true;
                opt.TokenCleanupInterval = 30;
            })
            .AddResourceOwnerValidator <ResourceOwnerPasswordValidator>();
        }
예제 #26
0
        public void Remove(ApiResource obj)
        {
            var apiResource = DbSet.FirstOrDefault(w => w.Name == obj.Name);

            DbSet.Remove(apiResource);
        }
예제 #27
0
 public static void Scope(this ApiResource resource, Scope scope)
 {
     resource.Scopes ??= new List <Scope>();
     resource.Scopes.Add(scope);
 }
예제 #28
0
 public void Add(ApiResource obj)
 {
     DbSet.Add(obj.ToEntity());
 }
예제 #29
0
 public static ApiResource ToEntity(this Models.ApiResource resource)
 {
     return(resource == null ? null : Mapper.Map <ApiResource>(resource));
 }
 /// <summary>
 /// Maps a model to an entity.
 /// </summary>
 /// <param name="model">The model.</param>
 /// <returns></returns>
 public static ApiResource ToEntity(this Ids4.ApiResource model)
 {
     return(model == null ? null : Mapper.Map <ApiResource>(model));
 }