public async Task UpdateAsync(string clientId, ClientUpdateDto model, IEnumerable <string> allowedClientIds = null) { ICollection <string> allowedCorsOrigins = null; if (model.AllowedCorsOrigins != null) { allowedCorsOrigins = model.AllowedCorsOrigins.Split(",", StringSplitOptions.RemoveEmptyEntries); foreach (var itm in allowedCorsOrigins) { if (!itm.IsUrl()) { throw new IamException(HttpStatusCode.BadRequest, $"{itm} 并不是合法的允许的跨域地址,必须是 Url 形式"); } } } if (!String.IsNullOrWhiteSpace(model.ClientUri) && !model.ClientUri.IsUrl()) { throw new IamException(HttpStatusCode.BadRequest, $"{model.ClientUri} 并不是合法的客户端地址,必须是 Url 形式"); } if (allowedClientIds != null && !allowedClientIds.Contains(clientId)) { throw new IamException(HttpStatusCode.BadRequest, "无权操作"); } var client = await _clientRepo.GetRawClientAsync(clientId, false); if (client == null) { throw new IamException(HttpStatusCode.BadRequest, "Client 不存在"); } if (!String.IsNullOrWhiteSpace(model.ClientUri) && client.ClientUri != model.ClientUri) { if (await _clientRepo.IsExistedAsync(model.ClientUri)) { throw new IamException(HttpStatusCode.BadRequest, "该客户端地址已经存在!"); } } List <string> allowedScopes = null; if (model.AllowedScopes != null && !String.IsNullOrWhiteSpace(model.AllowedScopes)) { allowedScopes = model.AllowedScopes.Split(",", StringSplitOptions.RemoveEmptyEntries).Select(sp => sp.Trim()).ToList(); // 排除 id scopes 以及 已经存在的 api scopes var newScopes = allowedScopes.Except(await _clientRepo.GetIdentityResourceNamesAsync(allowedScopes)) .Except(await _clientRepo.GetApiResourceNamesAsync(allowedScopes)); _clientRepo.AddApiResources(newScopes); // 增加 IAM 需要的 scopes if (!allowedScopes.Contains("iam")) { allowedScopes.Add("iam"); } if (!allowedScopes.Contains("iamApi")) { allowedScopes.Add("iamApi"); } if (!allowedScopes.Contains("openid")) { allowedScopes.Add("openid"); } if (!allowedScopes.Contains("profile")) { allowedScopes.Add("profile"); } if (!allowedScopes.Contains(IdentityServerConstants.StandardScopes.OfflineAccess)) { allowedScopes.Add(IdentityServerConstants.StandardScopes.OfflineAccess); } } string[] redirectUris = null; string[] postLogoutRedirectUris = null; if (model.RedirectUris != null && String.IsNullOrWhiteSpace(model.RedirectUris)) { redirectUris = new[] { $"{model.ClientUri.TrimEnd('/')}/signin-oidc" }; } else { redirectUris = model.RedirectUris?.Split(",", StringSplitOptions.RemoveEmptyEntries); } if (model.PostLogoutRedirectUris != null && String.IsNullOrWhiteSpace(model.PostLogoutRedirectUris)) { postLogoutRedirectUris = new[] { $"{model.ClientUri.TrimEnd('/')}/signout-callback-oidc" }; } else { postLogoutRedirectUris = model.PostLogoutRedirectUris?.Split(",", StringSplitOptions.RemoveEmptyEntries); } var clientModel = client.ToModel(); clientModel.ClientName = model.ClientName ?? clientModel.ClientName; clientModel.AccessTokenLifetime = model.AccessTokenLifetime ?? clientModel.AccessTokenLifetime; clientModel.AllowedCorsOrigins = model.AllowedCorsOrigins == null ? clientModel.AllowedCorsOrigins : (String.IsNullOrWhiteSpace(model.AllowedCorsOrigins) ? null : model.AllowedCorsOrigins.Split(",")); clientModel.AlwaysSendClientClaims = model.AlwaysSendClientClaims ?? clientModel.AlwaysSendClientClaims; clientModel.AllowedScopes = allowedScopes == null ? clientModel.AllowedScopes : allowedScopes; clientModel.Description = model.Description ?? clientModel.Description; clientModel.Enabled = model.IsEnabled; clientModel.IdentityTokenLifetime = model.IdentityTokenLifetime ?? clientModel.IdentityTokenLifetime; clientModel.LogoUri = model.LogoUri ?? (String.IsNullOrWhiteSpace(clientModel.LogoUri) ? null : clientModel.LogoUri); clientModel.ClientUri = model.ClientUri ?? (String.IsNullOrWhiteSpace(clientModel.ClientUri) ? null : clientModel.ClientUri); clientModel.RedirectUris = redirectUris == null ? clientModel.RedirectUris : redirectUris; clientModel.PostLogoutRedirectUris = postLogoutRedirectUris == null ? clientModel.PostLogoutRedirectUris : postLogoutRedirectUris; var updatedClient = clientModel.ToEntity(); client.ClientName = updatedClient.ClientName; client.AccessTokenLifetime = updatedClient.AccessTokenLifetime; client.AllowedCorsOrigins?.Clear(); client.AllowedCorsOrigins = updatedClient.AllowedCorsOrigins; client.AlwaysSendClientClaims = updatedClient.AlwaysSendClientClaims; client.AllowedScopes?.Clear(); client.AllowedScopes = updatedClient.AllowedScopes; client.Description = updatedClient.Description; client.Enabled = updatedClient.Enabled; client.IdentityTokenLifetime = updatedClient.IdentityTokenLifetime; client.LogoUri = updatedClient.LogoUri; client.ClientUri = updatedClient.ClientUri; client.RedirectUris?.Clear(); client.RedirectUris = updatedClient.RedirectUris; client.PostLogoutRedirectUris = updatedClient.PostLogoutRedirectUris; }