ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

id4 使用 授权码模式授权

2022-01-25 22:34:43  阅读:135  来源: 互联网

标签:code string id4 模式 token using 授权 app options


1 添加客户端

设置好clientid,添加客户端密钥,设置允许的作用域(scope)加上 openid 和 profile以及其它允许访问的scope,允许离线访问(请求 token 的时候scope要加上offline_access 会返回 refresh token),设置好重定向url(接收code的地址),设置好允许的授权类型为 authorization_code

2 mvc 客户端相关代码

startup.cs 代码如下:

using IdentityModel;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using System.IdentityModel.Tokens.Jwt;

namespace MvcClient
{
    public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddControllersWithViews();

            // 添加认证
            services.AddAuthentication("IdentityCookieAuthenScheme").AddCookie("IdentityCookieAuthenScheme", options =>
            {
                // sso 登录
                options.LoginPath = "/Login/Index"; // Authorize 失败后的回调地址
                // 本地登录
                //options.LoginPath = "/Login/LocalIndex";

                options.Cookie.Name = "AuthCookie";
            });

            //JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear(); // 包 System.IdentityModel.Tokens.Jwt;
            //services.AddAuthentication(options =>
            //{
            //    options.DefaultScheme = "Cookies";
            //    options.DefaultChallengeScheme = "oidc";
            //})
            //.AddCookie("Cookies", options =>
            //{
            //    options.LoginPath = "/Login/Index"; // 未认证的回跳地址
            //    options.Cookie.Name = "AuthCookie";
            //})
            //.AddOpenIdConnect("oidc", options => // 安装包 Microsoft.AspNetCore.Authentication.OpenIdConnect
            //{
            //    options.Authority = "https://localhost:44310"; // identity server 服务器地址
            //    options.SignInScheme = "Cookies";
            //    options.ClientId = "mvc_client";
            //    options.ClientSecret = "mvc_secret";
            //    options.ResponseType = "code";
            //    //options.RequireHttpsMetadata = false;
            //    options.SaveTokens = true; // 把获取到的token写入到cookie
            //    options.Scope.Clear();
            //    options.Scope.Add("openid");
            //    options.Scope.Add("profile");
            //    options.Scope.Add(OidcConstants.StandardScopes.OfflineAccess);
            //});
        }

        // 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();
            }
            else
            {
                app.UseExceptionHandler("/Home/Error");
                // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
                app.UseHsts();
            }
            app.UseHttpsRedirection();
            app.UseStaticFiles();

            app.UseRouting();

            app.UseAuthentication();
            app.UseAuthorization();

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllerRoute(
                    name: "default",
                    pattern: "{controller=Home}/{action=Index}/{id?}");
            });
        }
    }
}
using IdentityModel;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using System.IdentityModel.Tokens.Jwt;

namespace MvcClient
{
    public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddControllersWithViews();

            // 添加认证
            services.AddAuthentication("IdentityCookieAuthenScheme").AddCookie("IdentityCookieAuthenScheme", options =>
            {
                // sso 登录
                options.LoginPath = "/Login/Index"; // Authorize 失败后的回调地址
                // 本地登录
                //options.LoginPath = "/Login/LocalIndex";

                options.Cookie.Name = "AuthCookie";
            });

            //JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear(); // 包 System.IdentityModel.Tokens.Jwt;
            //services.AddAuthentication(options =>
            //{
            //    options.DefaultScheme = "Cookies";
            //    options.DefaultChallengeScheme = "oidc";
            //})
            //.AddCookie("Cookies", options =>
            //{
            //    options.LoginPath = "/Login/Index"; // 未认证的回跳地址
            //    options.Cookie.Name = "AuthCookie";
            //})
            //.AddOpenIdConnect("oidc", options => // 安装包 Microsoft.AspNetCore.Authentication.OpenIdConnect
            //{
            //    options.Authority = "https://localhost:44310"; // identity server 服务器地址
            //    options.SignInScheme = "Cookies";
            //    options.ClientId = "mvc_client";
            //    options.ClientSecret = "mvc_secret";
            //    options.ResponseType = "code";
            //    //options.RequireHttpsMetadata = false;
            //    options.SaveTokens = true; // 把获取到的token写入到cookie
            //    options.Scope.Clear();
            //    options.Scope.Add("openid");
            //    options.Scope.Add("profile");
            //    options.Scope.Add(OidcConstants.StandardScopes.OfflineAccess);
            //});
        }

        // 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();
            }
            else
            {
                app.UseExceptionHandler("/Home/Error");
                // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
                app.UseHsts();
            }
            app.UseHttpsRedirection();
            app.UseStaticFiles();

            app.UseRouting();

            app.UseAuthentication();
            app.UseAuthorization();

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllerRoute(
                    name: "default",
                    pattern: "{controller=Home}/{action=Index}/{id?}");
            });
        }
    }
}

未认证用户处理 LoginController 代码如下:

using Microsoft.AspNetCore.Mvc;
using System.Text;
using System.Net.Http;
using System.IO;
using Newtonsoft.Json.Linq;

namespace MvcClient.Controllers
{
    public class LoginController : Controller
    {
        private static string clientId = "mvc_client";
        private static string clientSecret = "mvc_secret";
        private static string id4Server = "https://localhost:44310";// 5001  44310
        private static string scope = "openid profile offline_access client_credentials_apis.WeatherForecastController.scope"; // 获取指定scope的token才有权调用该scope对应的apiresource 加上 offline_access 会返回 refresh token
        private static string redirectUri = "https://localhost:7001/Login/Callback"; // 接口code的地址

        public IActionResult Index()
        {
            //// 未登录
            // 从授权服务器获取 code
            string url = $"{id4Server}/connect/authorize?client_id={clientId}&response_type=code&scope={scope}&redirect_uri={redirectUri}&state=custom_state";
            return Redirect(url);
        }

        /// <summary>
        /// code 回调
        /// </summary>
        /// <param name="code"></param>
        /// <param name="state">自定义值</param>
        /// <returns></returns>
        public IActionResult Callback(string code, string state)
        {
            if (string.IsNullOrWhiteSpace(code))
                return Json(new { code = 0,msg="获取 code 失败"});

            string accessToken = string.Empty;
            string refreshToken = string.Empty;

            /*
             * 根据code 换取 access token
             */
            var postData = $"grant_type=authorization_code&code={code}&client_id={clientId}&client_secret={clientSecret}&redirect_uri={redirectUri}";
            var requestBody = Encoding.UTF8.GetBytes(postData);
            // 设置请求体类型
            string requestContentType = "application/x-www-form-urlencoded";
            using (HttpClient http = new HttpClient())
            {
                HttpResponseMessage message = null;
                using (Stream requestBodyStream = new MemoryStream(requestBody ?? new byte[0]))
                {
                    using (HttpContent content = new StreamContent(requestBodyStream))
                    {
                        content.Headers.Add("Content-Type", requestContentType);
                        var task = http.PostAsync(id4Server + "/connect/token", content);
                        message = task.Result;
                    }
                }
                using (message)
                {
                    string result = message.Content.ReadAsStringAsync().Result;
                    var json = JObject.Parse(result);
                    accessToken = json.GetValue("access_token").ToString();
                    refreshToken = json["refresh_token"].ToString();
                }
            }

            /*
             * 使用 access token 访问受保护资源
             */
            using (HttpClient httpclient = new HttpClient())
            {
                // 不使用token访问
                // 401 (Unauthorized).)
                //string res1 = httpclient.GetStringAsync("https://localhost:6001/Identity/Get").Result;

                // 使用 token 访问
                httpclient.DefaultRequestHeaders.Add("Authorization", "Bearer " + accessToken);
                var apiRes1 = httpclient.GetStringAsync($"https://localhost:6001/Test/Ping").Result;
                // 有token就能访问且 client allowedscope 包含 client_credentials_apis.WeatherForecastController.scope 才能访问
                var res_res3 = httpclient.GetStringAsync($"https://localhost:6001/WeatherForecast/Ping").Result;
                // 有token就能访问且 client allowedscope 包含 client_credentials_apis.IdentityUserController.scope 才能访问
                //var apiRes2 = httpclient.GetStringAsync($"https://localhost:6001/IdentityUser/Ping").Result;
            }

            // 通过 refresh token 刷新 access token
            var postData1 = $"grant_type=refresh_token&client_id={clientId}&client_secret={clientSecret}&refresh_token={refreshToken}";
            var requestBody1 = Encoding.UTF8.GetBytes(postData1);
            using (HttpClient http = new HttpClient())
            {
                HttpResponseMessage message = null;
                using (Stream requestBodyStream = new MemoryStream(requestBody1 ?? new byte[0]))
                {
                    using (HttpContent content = new StreamContent(requestBodyStream))
                    {
                        content.Headers.Add("Content-Type", requestContentType);
                        var task = http.PostAsync(id4Server + "/connect/token", content);
                        message = task.Result;
                    }
                }
                using (message)
                {
                    string result = message.Content.ReadAsStringAsync().Result;
                    var json = JObject.Parse(result);
                    accessToken = json.GetValue("access_token").ToString();

                    http.DefaultRequestHeaders.Add("Authorization", "Bearer " + accessToken);
                    // 有token就能访问
                    var userInfoRes = http.GetStringAsync($"{id4Server}/connect/userinfo").Result;
                }
            }

            return Json(new { code = 0, msg = "OK", data = new { code, state } });
        }
    }
}

 

标签:code,string,id4,模式,token,using,授权,app,options
来源: https://www.cnblogs.com/tomorrow0/p/15844678.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有