id4 使用 password 授权

1 添加 client

设置clientid,添加client密钥,设置授权类型为 “passwrod”,设置允许访问的scope(作用域) 至少添加 openid 不然 无法调用 userinfo 端点,也应该至少添加一个 api 资源关联的 scope,不然请求到的 token只能访问 identity resource (即 openid,role,profile 等等)的信息,无法访问 api resource 。

2 使用httpclient请求代码如下

using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.IO;
using System.Net.Http;
using System.Text;

namespace ConsoleClient
{
    /// <summary>
    /// 使用 HttpClient 通过密码方式获取token和资源
    /// 适用场景:一般用于兼容老应用,这种方式需要用户给出自己的用户名/密码,显然风险很大,因此只适用于其他授权方式都无法采用的情况
    /// </summary>
    public class HttpClient_Password
    {
        public static void Run()
        {
            // 先获取 access token
            // 如果不设置 scope 则获取所有允许的scope
            var token_res = string.Empty;
            /// 请求token链接格式:{idsServer}/connect/token?client_id={}&client_secret={}username={}&password={}&grant_type=password
            string postData = $"client_id=password&client_secret=123456&username=admin&password=@123456Ty&grant_type=password";
            using (var httpClient = new HttpClient())
            {
                using (HttpContent httpContent = new StreamContent(new MemoryStream(Encoding.UTF8.GetBytes(postData))))
                {
                    httpContent.Headers.Add("Content-Type", "application/x-www-form-urlencoded");
                    token_res = httpClient.PostAsync($"{Config.IdentityServerUri}/connect/token", httpContent).Result.Content.ReadAsStringAsync().Result;
                }
            }

            // 获取 userinfo 端点用户信息 一定要包含 openid scope 作用域
            if(JObject.Parse(token_res)["error"]?.ToString() == null)
            {
                using (HttpClient httpClient = new HttpClient())
                {
                    httpClient.DefaultRequestHeaders.Add("Authorization", "Bearer " + JObject.Parse(token_res)["access_token"].ToString());
                    // 有token就能访问
                    var userInfoRes = httpClient.GetStringAsync($"{Config.IdentityServerUri}/connect/userinfo").Result;
                }
            }

            // 使用 token 访问资源
            if (JObject.Parse(token_res)["error"]?.ToString() == null)
            {
                using (HttpClient getClient = new HttpClient())
                {
                    getClient.DefaultRequestHeaders.Add("Authorization", "Bearer " + JObject.Parse(token_res)["access_token"].ToString());
                    // 有token就能访问
                    var apiRes1 = getClient.GetStringAsync($"{Config.ResourceUri}/Test/Ping").Result;
                    // 有token就能访问且 client allowedscope 包含 client_credentials_apis.IdentityUserController.scope 才能访问
                    var apiRes2 = getClient.GetStringAsync($"{Config.ResourceUri}/IdentityUser/Ping").Result;
                    //// 有token就能访问且 client allowedscope 包含 client_credentials_apis.WeatherForecastController.scope 才能访问
                    //var res_res3 = getClient.GetStringAsync($"{Config.ResourceUri}/WeatherForecast/Ping").Result;
                }
            }
        }
    }
}

 

posted @ 2022-01-24 22:51  温故纳新  阅读(295)  评论(0编辑  收藏  举报