天天看点

.NET Core集成Identityserver4一、IdentityServer4是什么?二、使用步骤

文章目录

  • 一、IdentityServer4是什么?
  • 二、使用步骤
    • 1.创建一个认证服务项目,命名IdentityServer
    • 2.引入IdentityServer4库 版本3.1.4
    • 3.创建一个Config配置类
    • 4.定义一个api
    • 5.定义客户端
    • 6.添加用户
    • 7.配置Identityserver
    • 8.整个Config代码
    • 9.启动,运行
    • 10.通过postman进行测试

一、IdentityServer4是什么?

IdentityServer4 是为ASP.NET Core 2.系列量身打造的一款基于 OpenID Connect 和 OAuth 2.0 认证框架。将identityserver部署在你的应用中,具备如下的特点可以为你的应用(如网站、本地应用、移动端、服务)做集中式的登录逻辑和工作流控制。IdentityServer是完全实现了OpenID Connect协议标准。在各种类型的应用上实现单点登录登出。为各种各样的客户端颁发access token令牌,如服务与服务之间的通讯、网站应用、SPAS和本地应用或者移动应用等。

二、使用步骤

1.创建一个认证服务项目,命名IdentityServer

.NET Core集成Identityserver4一、IdentityServer4是什么?二、使用步骤

2.引入IdentityServer4库 版本3.1.4

.NET Core集成Identityserver4一、IdentityServer4是什么?二、使用步骤

3.创建一个Config配置类

4.定义一个api

范围(Scopes)用来定义系统中你想要保护的资源,比如 API。由于当前演练中我们使用的是内存配置 —— 添加一个 API,你需要做的只是创建一个 ApiResource 类型的实例,并为它设置合适的属性(代码示例):

public static IEnumerable<ApiResource> GetApis()
        {
            return new List<ApiResource>
            {
                new ApiResource("api", "Demo API")
                {
                    ApiSecrets = { new Secret("secret".Sha256()) }
                  
                },
                 new ApiResource("secretapi", "secretapi")
                {
                    ApiSecrets = { new Secret("secret".Sha256()) }

                }
                
            };
        }
           

5.定义客户端

下一步是定义能够访问上述 API 的客户端。在该场景中,客户端不会有用户参与交互,并且将使用 IdentityServer 中所谓的客户端密码(Client Secret)来认证。(代码示例):

public static IEnumerable<Client> GetClients()
        {
            return new List<Client>
                {
                    //走客户端模式
                    new Client
                    {
                        ClientId = "client",
                        ClientSecrets = { new Secret("secret".Sha256()) },
                        AllowedGrantTypes = GrantTypes.ClientCredentials,
                         //过期时间
                         AccessTokenLifetime=100000000,
                
                        AllowedScopes = { "api" 
                        }
                    },
                   //走账号密码模式
                new Client()
                {
                    
                    ClientId = "apiClientPassword",
                    ClientSecrets = { new Secret("apiSecret".Sha256()) },
                    AccessTokenLifetime = 1800,//设置AccessToken过期时间
                    AllowedGrantTypes =GrantTypes.ResourceOwnerPassword,
                    //RefreshTokenExpiration = TokenExpiration.Absolute,//刷新令牌将在固定时间点到期
                    AbsoluteRefreshTokenLifetime = 2592000,//RefreshToken的最长生命周期,默认30天
                    RefreshTokenExpiration = TokenExpiration.Sliding,//刷新令牌时,将刷新RefreshToken的生命周期。RefreshToken的总生命周期不会超过AbsoluteRefreshTokenLifetime。
                    SlidingRefreshTokenLifetime = 3600,//以秒为单位滑动刷新令牌的生命周期。
                    //按照现有的设置,如果3600内没有使用RefreshToken,那么RefreshToken将失效。即便是在3600内一直有使用RefreshToken,RefreshToken的总生命周期不会超过30天。所有的时间都可以按实际需求调整。
                    AllowOfflineAccess = true,//如果要获取refresh_tokens ,必须把AllowOfflineAccess设置为true
                    AllowedScopes = new List<string>
                    {
                        "secretapi",
                        StandardScopes.OfflineAccess, //如果要获取refresh_tokens ,必须在scopes中加上OfflineAccess
                        StandardScopes.OpenId,//如果要获取id_token,必须在scopes中加上OpenId和Profile,id_token需要通过refresh_tokens获取AccessToken的时候才能拿到(还未找到原因)
                        StandardScopes.Profile//如果要获取id_token,必须在scopes中加上OpenId和Profile
                    }
                }
                };
        }
           

6.添加用户

就像基于内存存储的资源(即 范围 Scopes)和客户端一样,对于用户也可以这样做。

注意:查看基于 ASP.NET Identity 的快速入门以获得更多关于如何正确存储和管理用户账户的信息。

TestUser 类型表示一个测试用户及其身份信息。(代码示例):

public static List<TestUser> GetUsers()
        {
            return new List<TestUser>()
        {
            new TestUser()
            {
                //用户名
                 Username="apiUser",
                 //密码
                 Password="apiUserPassword",
                 //用户Id
                 SubjectId="0",
                 Claims=new List<Claim>(){
                     new Claim(ClaimTypes.Role,"admin")
                 }
            }
        };
           

7.配置Identityserver

为了让 IdentityServer 使用你的 Scopes 和 客户端 定义,你需要向 ConfigureServices 方法中添加一些代码。你可以使用便捷的扩展方法来实现 —— 它们在幕后会添加相关的存储和数据到 DI 系统中(代码示例):

public void ConfigureServices(IServiceCollection services)
        {
            services.AddControllers();
//把配置添加到内存
            services.AddIdentityServer().AddInMemoryApiResources(Config.GetApis())
    .AddInMemoryIdentityResources(Config.GetIdentityResources())
     .AddTestUsers(Config.GetUsers())
    .AddInMemoryClients(Config.GetClients())
    .AddDeveloperSigningCredential();
        }
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            app.UseRouting();

            app.UseAuthorization();
            //配置UseIdentityServer
            app.UseIdentityServer();
            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllers();
            });
        }
           

8.整个Config代码

public class Config
    {
        public static IEnumerable<IdentityResource> GetIdentityResources()
        {
            return new List<IdentityResource>
            {
                new IdentityResources.OpenId(), 
                new IdentityResources.Profile(),
            };
        }
        public static List<TestUser> GetUsers()
        {
            return new List<TestUser>()
        {
            new TestUser()
            {
                //用户名
                 Username="apiUser",
                 //密码
                 Password="apiUserPassword",
                 //用户Id
                 SubjectId="0",
                 Claims=new List<Claim>(){
                     new Claim(ClaimTypes.Role,"admin")
                 }
            }
        };
        }
  
        public static IEnumerable<ApiResource> GetApis()
        {
            return new List<ApiResource>
            {
                new ApiResource("api", "Demo API")
                {
                    ApiSecrets = { new Secret("secret".Sha256()) }
                  
                },
                 new ApiResource("secretapi", "secretapi")
                {
                    ApiSecrets = { new Secret("secret".Sha256()) }

                }
                
            };
        }
        public static IEnumerable<Client> GetClients()
        {
            return new List<Client>
                {
                    //走客户端模式
                    new Client
                    {
                        ClientId = "client",
                        ClientSecrets = { new Secret("secret".Sha256()) },
                        AllowedGrantTypes = GrantTypes.ClientCredentials,
                         //过期时间
                         AccessTokenLifetime=100000000,
                          
                        AllowedScopes = { "api" 
                        }
                    },
                   //走账号密码模式
                new Client()
                {
                    
                    ClientId = "apiClientPassword",
                    ClientSecrets = { new Secret("apiSecret".Sha256()) },
                    AccessTokenLifetime = 1800,//设置AccessToken过期时间
                    AllowedGrantTypes =GrantTypes.ResourceOwnerPassword,
                    //RefreshTokenExpiration = TokenExpiration.Absolute,//刷新令牌将在固定时间点到期
                    AbsoluteRefreshTokenLifetime = 2592000,//RefreshToken的最长生命周期,默认30天
                    RefreshTokenExpiration = TokenExpiration.Sliding,//刷新令牌时,将刷新RefreshToken的生命周期。RefreshToken的总生命周期不会超过AbsoluteRefreshTokenLifetime。
                    SlidingRefreshTokenLifetime = 3600,//以秒为单位滑动刷新令牌的生命周期。
                    //按照现有的设置,如果3600内没有使用RefreshToken,那么RefreshToken将失效。即便是在3600内一直有使用RefreshToken,RefreshToken的总生命周期不会超过30天。所有的时间都可以按实际需求调整。
                    AllowOfflineAccess = true,//如果要获取refresh_tokens ,必须把AllowOfflineAccess设置为true
                    AllowedScopes = new List<string>
                    {
                        "secretapi",
                        StandardScopes.OfflineAccess, //如果要获取refresh_tokens ,必须在scopes中加上OfflineAccess
                        StandardScopes.OpenId,//如果要获取id_token,必须在scopes中加上OpenId和Profile,id_token需要通过refresh_tokens获取AccessToken的时候才能拿到(还未找到原因)
                        StandardScopes.Profile//如果要获取id_token,必须在scopes中加上OpenId和Profile
                    }
                }
                };
        }
    }
           

9.启动,运行

现在,如果你运行服务器并将浏览器导航到 http://localhost:5000/.well-known/openid-configuration,你应该看能到所谓的 发现文档。你的客户端和 API 将使用这些信息来下载所需要的配置数据。

.NET Core集成Identityserver4一、IdentityServer4是什么?二、使用步骤

10.通过postman进行测试

请求地址:http://localhost:5000/connect/token

  1. 测试客户端模式

    参数:

    grant_type=client_credentials

    client_id=client

    client_secret=secret

    Scope=api

    .NET Core集成Identityserver4一、IdentityServer4是什么?二、使用步骤
  2. 测试密码模式

    参数:

    grant_type=password

    client_id=client

    client_secret=secret

    Scope=api offline_access (必须配置offline_access,才能获取到refresh_token)

    Username=apiUser

    Password=apiUserPassword

    .NET Core集成Identityserver4一、IdentityServer4是什么?二、使用步骤