NETCORE - IdentityServer4 身份认证
官网:http://www.identityserver.com.cn/Home/Detail/shiyongpingzhengbaohuapi
ABP中身份认证可参考 :https://www.cnblogs.com/1285026182YUAN/p/15190387.html
Ocelot中的身份认证可参考:https://www.cnblogs.com/1285026182YUAN/p/15402841.html
单点登录参考:https://www.cnblogs.com/1285026182YUAN/p/15251708.html
IdentityServer4是基于openid+auth2.0基础实现的一整套完善的授权中心
1. OAuth 2.0是有关如何颁发访问令牌的规范,提供Access Token用于访问服务接口的 2. OpenID Connect是有关如何发行ID令牌的规范,提供Id Token用于用户身份标识,Id Token是基于JWT格式
案例环境:vs2019 , net core , webapi , .net5
1. 创建项目:NETCORE.IdentityServer4.Service
2. 新增 Config.cs 类
public class Config { //下载ids4的依赖 //scopes define the resources in your system public static IEnumerable<IdentityResource> GetIdentityResources() { return new List<IdentityResource> { new IdentityResources.OpenId(), new IdentityResources.Profile() }; } public static IEnumerable<ApiResource> GetApiResources() { return new List<ApiResource> { new ApiResource("API1", "第一个接口") { //重要 Scopes = { "scope1" } } }; } public static IEnumerable<ApiScope> GetApiScopes() { return new List<ApiScope> { new ApiScope("scope1") }; } public static IEnumerable<TestUser> Users() { return new[] { new TestUser { SubjectId="1", Username="mail@qq.com", Password="password" } }; } // clients want to access resources (aka scopes) public static IEnumerable<Client> GetClients() { return new List<Client> { new Client { ClientId = "app", ClientSecrets={new Secret("secret".Sha256())}, AllowedGrantTypes = GrantTypes.ResourceOwnerPasswordAndClientCredentials, AllowedScopes = new List<string> { IdentityServerConstants.StandardScopes.OpenId, IdentityServerConstants.StandardScopes.Profile, "scope1" } } }; } }
3. 修改 startup.cs ,注入 IdentityService4
public void ConfigureServices(IServiceCollection services) { services.AddControllers(); services.AddSwaggerGen(c => { c.SwaggerDoc("v1", new OpenApiInfo { Title = "NETCORE.IdentityServer4.Service", Version = "v1" }); }); services.AddIdentityServer()//Ids4服务 .AddDeveloperSigningCredential()//添加开发人员签名凭据 .AddTestUsers(Config.Users().ToList()) .AddInMemoryIdentityResources(Config.GetIdentityResources())//添加内存apiresource .AddInMemoryApiResources(Config.GetApiResources()) .AddInMemoryApiScopes(Config.GetApiScopes()) .AddInMemoryClients(Config.GetClients());//把配置文件的client配置资源放到内存 }
public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); app.UseSwagger(); app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "NETCORE.IdentityServer4.Service v1")); } app.UseHttpsRedirection(); app.UseRouting(); //启动ids4中间件 app.UseIdentityServer(); app.UseAuthorization(); app.UseEndpoints(endpoints => { endpoints.MapControllers(); }); }
4. 启动项目
此时授权服务中心已经运行,可以访问以下接口获取得到ids4默认discovery endpoint(定义了一个服务发现的规范),它定义了一个api( /.well-known/openid-configuration ),这个api返回一个json数据结构,其中包含了一些OIDC中提供的服务以及其支持情况的描述信息,这样可以使得oidc服务的RP可以不再硬编码OIDC服务接口信息。
访问 https://localhost:5001/.well-known/openid-configuration
可得到如下数据:
{ "issuer": "http://localhost:5000", //发行网址,也就是说我们的权限验证站点 "jwks_uri": "http://localhost:5000/.well-known/openid-configuration/jwks", // 这个接口获取的是公钥,用于验证jwt的数字签名部分(数字签名由sso维护的私钥生成)用的。 "authorization_endpoint": "http://localhost:5000/connect/authorize", // 授权服务器的授权端点的URL "token_endpoint": "http://localhost:5000/connect/token", // 获取token的URL接口 "userinfo_endpoint": "http://localhost:5000/connect/userinfo", // 根据token获取用户信息 "end_session_endpoint": "http://localhost:5000/connect/endsession", // 登录注销 "check_session_iframe": "http://localhost:5000/connect/checksession", // 客户端对check_session_iframe执行监视,可以获取用户的登出状态 "revocation_endpoint": "http://localhost:5000/connect/revocation", // 这个网址允许撤销访问令牌(仅access tokens 和reference tokens)。它实现了令牌撤销规范(RFC 7009) "introspection_endpoint": "http://localhost:5000/connect/introspect", // introspection_endpoint是RFC 7662的实现。 它可以用于验证reference tokens(或如果消费者不支持适当的JWT或加密库,则JWTs) "device_authorization_endpoint": "http://localhost:5000/connect/deviceauthorization", // "frontchannel_logout_supported": true, // 可选。基于前端的注销机制 "frontchannel_logout_session_supported": true, // 可选。基于session的注销机制 "backchannel_logout_supported": true, // 指示OP支持后端通道注销 "backchannel_logout_session_supported": true, // 可选的。指定RP是否需要在注销令牌中包含sid(session ID)声明,以在使用backchannel_logout_uri时用OP标识RP会话。如果省略,默认值为false "scopes_supported": [ "openid", "profile", "scope1", "offline_access" ], // 支持的范围 "claims_supported": [ "sub", "name", "family_name", "given_name", "middle_name", "nickname", "preferred_username", "profile", "picture", "website", "gender", "birthdate", "zoneinfo", "locale", "updated_at" ], // 支持的claims "grant_types_supported": [ "authorization_code", "client_credentials", "refresh_token", "implicit", "password", "urn:ietf:params:oauth:grant-type:device_code" ], // 授权类型 "response_types_supported": [ "code", "token", "id_token", "id_token token", "code id_token", "code token", "code id_token token" ], // 支持的请求方式 "response_modes_supported": [ "form_post", "query", "fragment" ], // 传值方式 "token_endpoint_auth_methods_supported": [ "client_secret_basic", "client_secret_post" ], // JSON数组,包含此令牌端点支持的客户端身份验证方法列表 "id_token_signing_alg_values_supported": [ "RS256" ], "subject_types_supported": [ "public" ], // JSON数组,包含此OP支持的主题标识符类型列表。 有效值是 pairwise 和 public.类型。 更多信息 "code_challenge_methods_supported": [ "plain", "S256" ], // JSON数组,包含此授权服务器支持的PKCE代码方法列表 "request_parameter_supported": true }
5. 获取token
由于之前配置的GrantTypes.ResourceOwnerPasswordAndClientCredentials模式,同时支持password和client_credentials两种模式访问
1) 使用password模式授权,注意使用 x-www-form-urlencoded 方式
地址:https://localhost:5001/connect/token
参数:
grant_type | password |
client_id | app |
client_secret | secret |
username | mail@qq.com |
password | password |
2) 使用 client_credentials 模式授权,注意使用 x-www-form-urlencoded 方式
地址:https://localhost:5001/connect/token
参数:
grant_type | password |
client_id | app |
client_secret | secret |
参考: https://blog.csdn.net/ml344739968/article/details/110640458
项目:NETCORE.IdentityServer4.ervice
附代码:https://gitee.com/wuxincaicai/NETCORE.git