IdentityServer4在.Net Core 3.1中应用(密码授权模式)


前言

密码授权模式是在客户端授权模式的基础代码上修改的,没有代码的可以查看我之前的那片文章。客户端验证模式


一、修改IdentityServer认证服务器?

1.1 修改Config文件

修改IdentityServer认证服务器项目中Config.cs类文件,添加密码模式的客户端。并配置基于内存的用户和密码。

using IdentityServer4.Models;
using IdentityServer4.Test;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace Sample.IdentityServer
{
    public class Config
    {

        /// <summary>
        /// 配置ApiResource
        /// </summary>
        /// <returns></returns>
        public static IEnumerable<ApiResource> ApiResources()
        {
            return new List<ApiResource>() {

                //将多个具体的ApiScope归为一个ApiResource。可将多个Api范围进行分组,
                //这样分的好处是对Api资源分的更细,在授权时,可更精细的控制。
               new ApiResource("Sample","IdentityServer4学习用例"){

                    Scopes={ "sample_api","demo_api" }
               }
            };

        }


        /// <summary>
        /// 设置具体的Api的范围
        /// </summary>
        public static IEnumerable<ApiScope> ApiScopes()
        {
            return new List<ApiScope>(){

               new ApiScope("sample_api","Sample Api"),
               new ApiScope("demo_api","Demo Api")

            };
        }

        /// <summary>
        /// 配置客户端应用
        /// </summary>
        public static IEnumerable<Client> Clients()
        {
            return new List<Client> {

                //客户端模式
                new Client{
                //客户端ID
                ClientId = "sample_api",

                //认证秘钥
                ClientSecrets = { new Secret("sample_client_secret".Sha256()) },

                //认证模式:设置为客户端模式
                AllowedGrantTypes = GrantTypes.ClientCredentials,

                //设置客户端有权访问的范围
                AllowedScopes = { "sample_api" }
                },

                //密码模式
                new Client{
                    //客户端ID
                    ClientId="sample_api_password",

                    //认证秘钥
                    ClientSecrets = { new Secret("sample_client_secret".Sha256()) },

                    //认证模式:设置为客户端模式
                    AllowedGrantTypes=GrantTypes.ResourceOwnerPassword,

                     //设置客户端有权访问的范围
                    AllowedScopes={"sample_api" }

                },
        };
        }


        /// <summary>
        /// 配置可以被认证和授权的用户信息,存在于内存上。
        /// </summary>
        /// <returns></returns>
        public static List<TestUser> GetTestUsers()
        {
            return new List<TestUser>()
            {
                new TestUser{

                    SubjectId="1",
                    Username="demo",
                    Password="456"
                },

                new TestUser{
                    SubjectId="2",
                    Username="test",
                    Password="456"
                }
            };
        }
    }
}

1.2 修改DI容器

在Startup.ConfigureServices()方法中向DI容器添加关于加载用户信息的方法。

  public void ConfigureServices(IServiceCollection services)
        {
            services.AddControllers();
            //将IdentityServer注册到DI容器当中
            services.AddIdentityServer()
                .AddDeveloperSigningCredential()   //在开发模式下自动生成JWT的秘钥,实际运行过程中需要自己生成秘钥。
              //.AddSigningCredential()运用自己生成的秘钥。
                .AddInMemoryApiResources(Config.ApiResources())//注册ApiResource
                .AddInMemoryApiScopes(Config.ApiScopes())// 注册API的范围
                .AddInMemoryClients(Config.Clients())//注册Api的客户端
                .AddTestUsers(Config.GetTestUsers());//加载用户信息 (如果是客户端模式,可以不用写此方法)
        }

至此,IdentityServer认证服务器就修改完成了。

二、修改客户端

在客户端项目中修改关于密码方式的访问请求。

using System;
using System.Net.Http;
using System.Threading.Tasks;
using IdentityModel.Client;
using Newtonsoft.Json.Linq;

namespace Sample.Client
{
    class Program
    {
        static async Task Main(string[] args)
        {
            var client = new HttpClient();

            var disco = await client.GetDiscoveryDocumentAsync("http://localhost:5000");

            if (disco.IsError)
            {
                Console.WriteLine(disco.Error);
                return;
            }

            //客户端模式
            //var tokenRequest = await client.RequestClientCredentialsTokenAsync(new ClientCredentialsTokenRequest
            //{

            //    Address = disco.TokenEndpoint,
            //    ClientId = "sample_api",
            //    ClientSecret = "sample_client_secret"
            //});

            //密码模式
            var tokenRequest = await client.RequestPasswordTokenAsync(new PasswordTokenRequest
            {
                Address = disco.TokenEndpoint,
                ClientId = "sample_api_password",
                ClientSecret = "sample_client_secret",
                UserName = "demo",
                Password = "456"
            });

            Console.WriteLine("IdentityServer4服务器返回的结果 : {0}", tokenRequest.Json);

            var apiClient = new HttpClient();

            apiClient.SetBearerToken(tokenRequest.AccessToken);

            var response = await apiClient.GetAsync("http://localhost:6000/WeatherForecast");

            if (!response.IsSuccessStatusCode)
            {
                Console.WriteLine(response.StatusCode);
                return;
            }

            var content = await response.Content.ReadAsStringAsync();

            Console.WriteLine(JArray.Parse(content));
            Console.ReadKey();
        }
    }
}

三、验证

3.1 启动项目

启动IdentityServer认证服务器和API资源服务器项目。

3.2 获取Access_Token(Postman)

与请求客户端模式不同,这里需要修改参数。

client_id的参数修改为 sample_api_password

grant_type的参数改为 password

添加username,参数为 demo

添加password,参数为 456

在这里插入图片描述
如上图所示,已经正确的拿到了Access_Token。

3.3 携带Access_Token请求API(Postman)

和客户端模式一样,将获取到的Access_Token填写到参数框中。发送请求。
在这里插入图片描述
如图所示,我们已经拿到了API资源服务器所返回的参数。

3.4 客户端验证

下面,我们运行客户端程序,查看返回结果。
在这里插入图片描述
客户端同样拿到了相同的数据,至此,密码授权模式完成。

如需要源码,请在Gitee上下载:IdentityServer4Demo

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值