IdentityServer4配置
服务项目建立
- 新建一个Asp.net Core Web 空项目,取名为Ids4
- 引入 IdentityServer4.AspNetIdentity Nuget包
- 引入 Consul Nuget包
修改配置文件
修改配置文件 appsettings.json
{
"ids4Config": {
"ApiScopes": [
{
"Name": "Gateway",
"DisplayName": "OcelotGateway"
}
],
"ApiResources": [
{
"Name": "idsApi",
"DisplayName": "idsApiName",
"Scopes": [ "Gateway" ]
}
],
"Clients": [
{
"ClientId": "Ocelot",
"ClientSecrets": [ "123456" ],
"AllowedGrantTypes": "ClientCredentials",
"AllowedScopes": [ "Gateway" ]
}
]
},
"urls": "http://localhost:6003", //当前服务的网址,根据项目属性中配置的进行修改
"consul_urls": "http://localhost:8500", //Consul服务的地址
"service_id": "1", //当前服务的ID
"service_name": "ids4" //当前服务的名称
}
读取IdentityServer4配置信息
- 新建一个类,命名 ApiConfig
namespace Ids4.Config
{
public class ApiConfig
{
public string Name { get; set; }
public string DisplayName { get; set; }
}
}
- 新建一个类,命名 ClientConfig
namespace Ids4.Config
{
public class ClientConfig
{
public string ClientId { get; set; }
public List<string> ClientSecrets { get; set; }
public string AllowedGrantTypes { get; set; }
public List<string> AllowedScopes { get; set; }
}
}
- 新建一个类,命名 Id4ServerConfig
namespace Ids4.Config
{
public class Id4ServerConfig
{
/// <summary>
/// 获得Api资源信息
/// </summary>
/// <param name="section"></param>
/// <returns></returns>
public static IEnumerable<ApiResource> GetApiResources(IConfigurationSection section)
{
List<ApiResource> resource = new List<ApiResource>();
if (section != null)
{
List<ApiConfig> configs = new List<ApiConfig>();
section.Bind("ApiResources", configs);
foreach (var config in configs)
{
resource.Add(new ApiResource(config.Name, config.DisplayName)
{
Scopes = { config.Name }
});
}
}
return resource;
}
public static IEnumerable<ApiScope> GetApiScopes(IConfigurationSection section)
{
List<ApiScope> resource = new List<ApiScope>();
if (section != null)
{
List<ApiConfig> configs = new List<ApiConfig>();
section.Bind("ApiScopes", configs);
foreach(var config in configs)
{
resource.Add(new ApiScope(config.Name, config.DisplayName));
}
}
return resource;
}
/// <summary>
/// 获得客户端信息
/// </summary>
/// <param name="section"></param>
/// <returns></returns>
public static IEnumerable<Client> GetClients(IConfigurationSection section)
{
List<Client> clients = new List<Client>();
if (section != null)
{
List<ClientConfig> configs = new List<ClientConfig>();
section.Bind("Clients", configs);
foreach(var config in configs)
{
Client client = new Client();
client.ClientId = config.ClientId;
List<Secret> secrets = new List<Secret>();
foreach(var secret in config.ClientSecrets)
{
secrets.Add(new Secret(secret.Sha256()));
}
client.ClientSecrets = secrets;
GrantTypes grantTypes = new GrantTypes();
var allowedGrantTypes = grantTypes.GetType().GetProperty(config.AllowedGrantTypes);
client.AllowedGrantTypes = allowedGrantTypes == null ? GrantTypes.ClientCredentials :
(ICollection<string>)allowedGrantTypes.GetValue(grantTypes, null);
client.AllowedScopes = config.AllowedScopes;
clients.Add(client);
}
}
return clients;
}
}
}
修改Startup.cs类,启动IdentityServer4及向Consul注册
修改ConfigureServices方法
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers();
services.AddConnections();
var section = _configuration.GetSection("ids4Config");
services.AddIdentityServer()
//设备临时签名凭据
.AddDeveloperSigningCredential()
//从配置文件中获得Api资源
.AddInMemoryApiResources(Id4ServerConfig.GetApiResources(section))
//从配置文件中获得Client集合
.AddInMemoryClients(Id4ServerConfig.GetClients(section))
.AddInMemoryApiScopes(Id4ServerConfig.GetApiScopes(section));
}
修改Configure方法
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseRouting();
app.UseIdentityServer();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
//向Consul服务注册
PublicHelper.RegSerToConsul(_configuration);
}
PublicHelper类和ApiA、ApiB项目中的PublicHelper一样
添加健康检查接口 HealthController
namespace Ids4.Contoller
{
[Route("api/[controller]")]
[ApiController]
public class HealthController : ControllerBase
{
public string Get() => "ok";
}
}
修改【Ocelot项目】中的相关配置文件
- 引入 IdentityServer4 Nuget包
- 引入 IdentityServer4.AccessTokenValidation Nuget包
- 修改【OcelotConfig.json】
{
"DownstreamPathTemplate": "/api/{url}", //下游地址模板,转发模板
"DownstreamScheme": "http", //下游转发协议
"UpstreamPathTemplate": "/ApiA/{url}", //上游匹配模板
"UpstreamHttpMethod": [ "Get", "Post" ], //上游匹配协议
"UseServiceDiscovery": true, //是否进行服务发现
"ServiceName": "ApiA", //服务名称
"LoadBalancerOptions": {
"Type": "RoundRobin" //负载均衡,转徇
},
//身份验证
"AuthenticationOptions": {
"AuthenticationProviderKey": "OcelotProviderKey",
"AllowScopes": []
}
}
- 修改【Startup.cs】
public void ConfigureServices(IServiceCollection services)
{
string authKey = "OcelotProviderKey";
services.AddAuthentication("Bearer")
.AddJwtBearer(authKey, op => {
op.Authority = "http://localhost: 6003"; // 授权认证的地址(Ids4服务地址)
op.Audience = "idsApi";//ApiResources的name(Ids4服务)
op.RequireHttpsMetadata = false;
op.SaveToken = true;
op.TokenValidationParameters = new Microsoft.IdentityModel.Tokens.TokenValidationParameters()
{
ValidateAudience = false
};
});
services.AddOcelot().AddConsul();
}
至此,所有配置已完成
启动相关项目测试
-
同时启动【OcelotService】、【ApiA】、【ApiB】、【Ids4】四个项目
-
通过 http://localhost:6000/ApiA/UserInfo 查询 ApiA 中的接口,可以看到 401错误
-
通过 http://localhost:6000/connect/token 查询token
-
把查询 的token放到Header中(使用Bearer),如下图
-
再次访问 http://localhost:6000/ApiA/UserInfo,成功获得,如下图
至此,所有配置完成,验证结果OK