NETCORE

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

原文地址:https://www.cnblogs.com/1285026182YUAN/p/15250347.html