博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Identity Server4学习系列三
阅读量:4591 次
发布时间:2019-06-09

本文共 8215 字,大约阅读时间需要 27 分钟。

1、简介

在和的基础上,了解了Identity Server4的由来,以及令牌的相关知识,本文开始实战,实现Identity Server4基本的功能。

 

2、前提

本文基于.Net Core2.1和Indetity Server4 2.3.0,令牌处理包采用IdentityServer4.AccessTokenValidation 2.7.0

 

3、实战一Identity Server4服务端配置

(1)、项目结构

 

(2)、站点入口文件Program.cs类

public class Program    {        public static void Main(string[] args)        {            CreateWebHostBuilder(args).Build().Run();        }        ///         /// 设置当前项目的服务器宿主,Windows下默认为IIS        /// 设置启动类为Startup类        ///         ///         /// 
public static IWebHostBuilder CreateWebHostBuilder(string[] args) => WebHost.CreateDefaultBuilder(args) .UseStartup
(); }

注意:如果时Linux环境,这里在这里可以切换站点的宿主服务器

 

(3)、Startup启动类(配置Identity Server4的相关参数和MVC的相关参数,并注入到管道模型中)

public class Startup    {        // This method gets called by the runtime. Use this method to add services to the container.        // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940        public void ConfigureServices(IServiceCollection services)        {            //优雅的链式编程            //注入Identity Server4服务到DI容器中            services.AddIdentityServer()           //注入临时签名凭据到DI容器,后期可用签名证书的密钥替换,用于生成零时密钥           .AddDeveloperSigningCredential()           //注入需要受Identity Server4保护的Api资源添注入到DI容器中 -内存级别           .AddInMemoryApiResources(Apis.GetApiResources())           //注入需要访问受Identity Server4保护的Api资源的客户端注入到DI容器中 -内存级别           .AddInMemoryClients(ThirdClients.GetClients());            //注入基本的MVC服务            services.AddMvcCore()            //注入MVC的认证服务,对应控制器的Authorize特性           .AddAuthorization()           //注入MVC格式化程序,对应JsonResult等等的格式化操作,主要用于控制器返回值的格式化操作           .AddJsonFormatters();            //注入身份认证服务,设置Bearer为默认方案            services.AddAuthentication("Bearer")            //注入并配置Bearer为默认方案的基本参数            .AddIdentityServerAuthentication(options =>            {                //设置令牌的发布者                options.Authority = "http://localhost:5000";                //设置Https                options.RequireHttpsMetadata = false;                //需要认证的api资源名称                options.ApiName = "api1";            });        }        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.        public void Configure(IApplicationBuilder app, IHostingEnvironment env)        {            //如果当前时开发者模式            if (env.IsDevelopment())            {                //从管道中捕获同步和异步System.Exception实例并生成HTML错误响应。                app.UseDeveloperExceptionPage();            }            //将IdentityServer 4服务注入到管道模型中(对应上面的IdentityServer 4服务的配置)            app.UseIdentityServer();            //将认证服务通过Microsoft.AspNetCore.Authentication.AuthenticationMiddleware中间件            //注入到管道模型中(对应上面认证服务的配置)            app.UseAuthentication();            //将mvc添加到Microsoft.AspNetCore.Builder.IApplicationBuilder请求执行中(对应上的MVC配置)            app.UseMvc();        }    }

 

(4)、配置第三方客户端能成功在认证模式下能成功访问Api资源的资本参数

///     /// 配置可以访问IdentityServer4 保护的Api资源模型的第三方客户端    /// 配置客户端访问的密钥    /// 配置    ///     public class ThirdClients    {        public static IEnumerable
GetClients() { return new List
() { new Client() { //客户端的唯一Id,客户端需要指定该ClientId才能访问 ClientId = $"client", //no interactive user, use the clientid/secret for authentication //使用客户端密钥进行认证 AllowedGrantTypes = GrantTypes.ClientCredentials, // 认证密钥 ClientSecrets = { //用Sha256对"secret"进行加密,客户端必须使用secret密钥才能成功访问 new Secret("secret".Sha256()) }, // scopes that client has access to //如果客户端的密钥认证成功,限定该密钥可以访问的Api范围 AllowedScopes = { "api1" } } }; } }

注意ClientId(分配给不同客户端的Id),对应的客户端调用时传递过来的ClientId必须一致,否则客户端发起调用时汇报这个错:

密钥也是一样,密钥是我们分配给客户端的,客户端只有给对了我们分配给它的ClientId和密钥的同时,才能访问对应的api,所以如果你的密钥不对,客户端发起调用时也会报这个错:

 

(5)、配置受保护的Api资源模型

public class Apis    {        //ApiResource -IdentityServer4.Models下的Api资源模型        public static IEnumerable
GetApiResources() { return new List
() { //Api资源模型 new ApiResource("api1", "My API") }; } }

注意ApiRescourse的名称必须和Client的AllowedScopes属性对应,否则客户端调用时会报下面这个错:

 

(6)、验证服务端是否配置成功

开启站点,浏览器输入http://localhost:5000/.well-known/openid-configuration,等到如下返回报文说明服务部署成功:

{
   //令牌签发者,对应StartUp中的Identity Server4中的认证配置 "issuer":"http://localhost:5000", //jwt令牌处理地址 "jwks_uri":"http://localhost:5000/.well-known/openid-configuration/jwks", "authorization_endpoint":"http://localhost:5000/connect/authorize", "token_endpoint":"http://localhost:5000/connect/token", "userinfo_endpoint":"http://localhost:5000/connect/userinfo", "end_session_endpoint":"http://localhost:5000/connect/endsession", "check_session_iframe":"http://localhost:5000/connect/checksession", "revocation_endpoint":"http://localhost:5000/connect/revocation", "introspection_endpoint":"http://localhost:5000/connect/introspect", "device_authorization_endpoint":"http://localhost:5000/connect/deviceauthorization", "frontchannel_logout_supported":true, "frontchannel_logout_session_supported":true, "backchannel_logout_supported":true, "backchannel_logout_session_supported":true, "scopes_supported":[ "api1", "offline_access" ], "claims_supported":[ ], "grant_types_supported":[ "authorization_code", "client_credentials", "refresh_token", "implicit", "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" ], "subject_types_supported":[ "public" ], "id_token_signing_alg_values_supported":[ "RS256" ], "code_challenge_methods_supported":[ "plain", "S256" ]}

参数含义,自行了解

 

3、实战一客户端调用受Identity Server4保护的Api资源

(1)、前提

客户端必须安装IdentityModel 3.10.4包

 

(2)、调用代码如下:

class Program    {        static void Main(string[] args)        {            Request();            Console.ReadKey();        }        async static void Request()        {            //请求Identity Server4服务            var disco = await DiscoveryClient.GetAsync("http://localhost:5000");            if (disco.IsError)            {                Console.WriteLine(disco.Error);                return;            }            //生成Identity Server4授权的客户端,通过指定对应的ClientId和密钥(secret)            var tokenClient = new TokenClient(disco.TokenEndpoint, "client", "secret");            var tokenResponse = await tokenClient.RequestClientCredentialsAsync("api1");            if (tokenResponse.IsError)            {                Console.WriteLine(tokenResponse.Error);                return;            }            Console.WriteLine(tokenResponse.Json);            //通过Identity Server4的认证过后,拿到AccessToken            var client = new HttpClient();            client.SetBearerToken(tokenResponse.AccessToken);            var response = await client.GetAsync("http://localhost:5000/identity");            if (!response.IsSuccessStatusCode)            {                Console.WriteLine(response.StatusCode);            }            else            {                //认证成功,输出Identity控制器的返回值                var content = await response.Content.ReadAsStringAsync();                Console.WriteLine(JArray.Parse(content));            }        }    }

得到如下报文:

同时查看Identity Server4服务端的输出:

第一步:客户端传入在Indetity Server4中注册过的分配给该客户端的ClientId和密钥,拿到AccessToken

 

第二步:第一次请求目标控制器,并把AcessToken带过去

第三步:验证Token是否有效

第四步:Token有效,开始调用Identity控制器方法,并拿到响应值

 大致的流程如上.

转载于:https://www.cnblogs.com/GreenLeaves/p/10123697.html

你可能感兴趣的文章
WPF与WinForm开发有什么区别?
查看>>
Python中用format函数格式化字符串
查看>>
黑马程序员——函数
查看>>
java开发环境配置(win8 64位)
查看>>
其中考试
查看>>
(8)zabbix监控项item是什么
查看>>
本人的coding地址
查看>>
json_encode
查看>>
洛谷 1164 小A点菜
查看>>
客户端连接服务端的配置文件
查看>>
【POJ - 1995】Raising Modulo Numbers(快速幂)
查看>>
python model对象转为dict数据
查看>>
RPC
查看>>
sql 转 markdown
查看>>
UI自动化笔记(二)
查看>>
WINDOWS 的 MKLINK : 硬链接,符号链接 : 文件符号链接, 目录符号链接 : 目录联接...
查看>>
HTML5VEDIO标签阿里云-微信浏览器兼容性问题
查看>>
jQuery事件和JavaScript事件
查看>>
webService 客户端 以wsimport方式生成对应java文件
查看>>
springmvc的请求流程
查看>>