• 微服务(入门四):identityServer的简单使用(客户端授权+密码授权)


    IdentityServer简介(摘自Identity官网)

    IdentityServer是将符合规范的OpenID Connect和OAuth 2.0端点添加到任意ASP.NET核心应用程序的中间件,通常,您构建(或重新使用)一个包含登录和注销页面的应用程序(可能还包括同意,具体取决于您的需要),IdentityServer中间件向其添加必要的协议头,以便客户端应用程序可以使用这些标准协议与之对话。

    托管应用程序可以像您希望的那样复杂,但我们通常建议通过只包含与身份验证相关的UI来尽可能地保持攻击面小。

     client               :客户端,从identityServer请求令牌,用户对用户身份校验,客户端必须先从identityServer中注册,然后才能请求令牌。

     sources           :每个资源都有自己唯一的名称,就是文中所定义的api1服务名称,indentity会验证判定是否有访问该资源的权限。

     access Token  :访问令牌,由identityServer服务器签发的,客户端使用该令牌进行访问拥有权限的api

     

    OAuth 2.0四种授权模式(GrantType)

    •  客户端模式(client_credentials)
    •  密码模式(password)
    •  授权码模式(authorization_code)
    •  简化模式(implicit)

    作用

    • 单点登录

            在多个应用程序当中进行统一登录或者注销。

    • api访问控制
      • 为各种类型的客户端(如服务器到服务器、Web应用程序、SPA和本机/移动应用程序)颁发API访问令牌。
    • 联盟网关

              支持外部身份提供商,如Azure Active Directory、Google、Facebook等。这将使您的应用程序不了解如何连接到这些外部提供商的详细信息。

    开发准备

       开发环境             :vs2019 

       identityServer4:2.4.0

      netcore版本       :2.1

    客户端授权模式介绍

    客户端模式的话是属于identityServer保护API的最基础的方案,我们定义个indentityServer服务以及一个需要保护的API服务,

    当客户端直接访问api的话,由于我们的api服务添加了authorization认证,所以必须要到identityServer放服务器上拿到访问令牌,客户端凭借该令牌去对应api服务当中获取想要得到的数据

    添加IdentityServer项目

      1.首先添加新项目,创建ASP.NET Core Web 应用程序  创建一个名称为identityServer4test的项目,选择项目类型API  项目进行创建。

    2.从程序包管理器控制台或者ngGet下载IdentityServer4

      2.1 程序包管理器控制台:install-package IdentityServer4

      2.2 NuGet 的话在对应的程序集,选择nuget输入IdentityServer4选择对应的版本进行下载安装

      

    3.添加Identity Server4 配置

       资源定义可以通过多种方式实现,具体的请查阅官方api文档:https://identityserver4.readthedocs.io/en/latest/quickstarts/1_client_credentials.html

     注:1.ApiResource("api1","My Api"),其中api1代表你的唯一资源名称,在 AllowedScopes = { "api1" }当中必须配置上才可以进行访问

    using IdentityServer4.Models;
    using IdentityServer4.Test;
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Threading.Tasks;
    
    namespace IdentityServer4Test.IndntityConfig
    {
        public class IdentityServerConfig
        {
            /// <summary>
            /// 添加api资源
            /// </summary>
            /// <returns></returns>
            public static IEnumerable<ApiResource> GetResources()
            {
                return new List<ApiResource>
                {
             
    new ApiResource("api1","My Api") }; } /// <summary> /// 添加客户端,定义一个可以访问此api的客户端 /// </summary> /// <returns></returns> public static IEnumerable<Client> GetClients() { return new List<Client> { new Client { /// ClientId = "client", // 没有交互性用户,使用 客户端模式 进行身份验证。 AllowedGrantTypes = GrantTypes.ClientCredentials, // 用于认证的密码 ClientSecrets = { new Secret("123454".Sha256()) }, // 客户端有权访问的范围(Scopes) AllowedScopes = { "api1" } } }; } } }

    4.在startUp当中注入IdentityServer4 服务

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Threading.Tasks;
    using IdentityServer4.Models;
    using IdentityServer4.Test;
    using IdentityServer4Test.IndntityConfig;
    using Microsoft.AspNetCore.Builder;
    using Microsoft.AspNetCore.Hosting;
    using Microsoft.AspNetCore.Mvc;
    using Microsoft.Extensions.Configuration;
    using Microsoft.Extensions.DependencyInjection;
    using Microsoft.Extensions.Logging;
    using Microsoft.Extensions.Options;
    
    namespace IdentityServer4Test
    {
        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.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
                // 在DI容器中注入identityServer服务
                services.AddIdentityServer()
             
            .AddInMemoryApiResources(IdentityServerConfig.GetResources())//添加配置的api资源
            .AddInMemoryClients(IdentityServerConfig.GetClients())//添加客户端,定义一个可以访问此api的客户端
                .AddDeveloperSigningCredential();
                
    
            }
            // 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())
                {
                    app.UseDeveloperExceptionPage();
                }
                //添加identityserver中间件到http管道
                app.UseIdentityServer();
                //app.UseMvc();
            }
        }
    }

    5.此时启动程序输入 http://localhost:3322/.well-known/openid-configuration可以得到如下网站,这是identity Server4 提供的配置文档

    6.用postMan请求获取access_token

      

    标注:body 当中的参数

            grant_type    :对应api AllowedGrantTypes 类型表示授权模式

            client_id        : 对应clentID 

            client_secret: 客户端秘钥

           

    7.拿到token以后就可以根据token去访问我们的服务程序,服务程序,首先也是创建一个webApi程序,并且从NuGet下载所需的依赖

    •    IdentityServer4.AccessTokenValidation(程序报管理器的话加上install-package IdentityServer4.AccessTokenValidation)

      7.1 配置authentication,并且添加    app.UseAuthentication();到http管道当中

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Threading.Tasks;
    using Microsoft.AspNetCore.Builder;
    using Microsoft.AspNetCore.Hosting;
    using Microsoft.AspNetCore.Mvc;
    using Microsoft.Extensions.Configuration;
    using Microsoft.Extensions.DependencyInjection;
    using Microsoft.Extensions.Logging;
    using Microsoft.Extensions.Options;
    
    namespace IndentityServerClientTest
    {
        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.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
                 //注入authentication服务
                services.AddAuthentication("Bearer")
                
                   .AddIdentityServerAuthentication(options =>
                   {
                       options.Authority = "http://localhost:3322";//IdentityServer服务地址
                       options.ApiName = "api1"; //服务的名称,对应Identity Server当中的Api资源名称,如果客户端得到的token可以访问此api的权限才可以访问,否则会报401错误
                       options.RequireHttpsMetadata = false;
                   });
    
            }
    
            // 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())
                {
                    app.UseDeveloperExceptionPage();
                }
                //添加authentication中间件到http管道
                app.UseAuthentication();
                app.UseMvc();
            }
        }
    }

    7.2 引用Microsoft.AspNetCore.Authorization;命名空间,添加authorize认证

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Threading.Tasks;
    using Microsoft.AspNetCore.Authorization;
    using Microsoft.AspNetCore.Mvc;
    
    namespace IndentityServerClientTest.Controllers
    {
        [Route("api/[controller]")]
        [ApiController]
        [Authorize]
        public class ValuesController : ControllerBase
        {
            // GET api/values
            [HttpGet]
            public ActionResult<IEnumerable<string>> Get()
            {
                return new string[] { "value1", "value2" };
            }
    
            // GET api/values/5
            [HttpGet("{id}")]
            public ActionResult<string> Get(int id)
            {
                return "value";
            }
    
            // POST api/values
            [HttpPost]
            public void Post([FromBody] string value)
            {
            }
    
            // PUT api/values/5
            [HttpPut("{id}")]
            public void Put(int id, [FromBody] string value)
            {
            }
    
            // DELETE api/values/5
            [HttpDelete("{id}")]
            public void Delete(int id)
            {
            }
    
            // DELETE api/values/5
            [Route("send")]
            [HttpGet]
            public string send()
            {
                return "成功了";
    
            }
    
        }
    }

    7.3. 直接访问的话会报401错误

    7.4 在请求头当中添加Authorization 参数,参数值为Bearer加上空格 加上咱们刚才获取到的access_token 请求成功!~~

     密码授权                                                         

      

    官方介绍

     OAuth2.0资源所有者密码授权允许客户端向令牌服务发送用户名和密码,并获取代表该用户的访问令牌。

     除了不能承载浏览器的遗留应用程序之外,规范通常建议不要使用资源所有者密码授予。一般来说,当您想要对用户进行身份验证并请求访问令牌时,最好使用交互式OpenID连接流之一。

     然而,这种授权类型允许我们将用户的概念引入到QuickStartIdentityServer,这就是我们展示它的原因。

     1.配置可访问的用户信息以及授权模式

       新添加一个client模式并且更改AllowedGrantTypes 类型为“GrantTypes.ResourceOwnerPassword” 

    using IdentityServer4.Models;
    using IdentityServer4.Test;
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Threading.Tasks;
    
    namespace IdentityServer4Test.IndntityConfig
    {
        public class IdentityServerConfig
        {
            /// <summary>
            /// 添加api资源
            /// </summary>
            /// <returns></returns>
            public static IEnumerable<ApiResource> GetResources()
            {
                return new List<ApiResource>
                {
                    new ApiResource("api1","My Api")
                };
            }
            /// <summary>
            /// 添加客户端,定义一个可以访问此api的客户端
            /// </summary>
            /// <returns></returns>
            public static IEnumerable<Client> GetClients()
            {
                return new List<Client>
                    {
                        new Client
                        {
                            ///
                            ClientId = "client",
    
                            // 没有交互性用户,使用 客户端模式 进行身份验证。
                            AllowedGrantTypes = GrantTypes.ClientCredentials,
                           
                            // 用于认证的密码
                            ClientSecrets =
                            {
                                new Secret("123454".Sha256())
                            },
                            // 客户端有权访问的范围(Scopes)
                            AllowedScopes = { "api1" }
                        }
                        ,
                        new Client
                        {
                            ClientId = "client1",
    
    
                            AllowedGrantTypes = GrantTypes.ResourceOwnerPassword,
                           
                            // 用于认证的密码
                            ClientSecrets =
                            {
                                new Secret("laozheng".Sha256())
                            },
                            RequireClientSecret=false,
                            // 客户端有权访问的范围(Scopes)
                            AllowedScopes = { "api1" }
                        }
                    };
    
            }
    
            public static List<TestUser> GetTestUsers()
            {
                return new List<TestUser> {
                    new TestUser{
                        SubjectId="1",
                        Password="111",
                        Username="111",
                    }
                };
            }
        }
    }
    

    1.1 修改startup.cs文件

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Threading.Tasks;
    using IdentityServer4.Models;
    using IdentityServer4.Test;
    using IdentityServer4Test.IndntityConfig;
    using Microsoft.AspNetCore.Builder;
    using Microsoft.AspNetCore.Hosting;
    using Microsoft.AspNetCore.Mvc;
    using Microsoft.Extensions.Configuration;
    using Microsoft.Extensions.DependencyInjection;
    using Microsoft.Extensions.Logging;
    using Microsoft.Extensions.Options;
    
    namespace IdentityServer4Test
    {
        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.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
                // 在DI容器中注入identityServer服务
                services.AddIdentityServer()
             
            .AddInMemoryApiResources(IdentityServerConfig.GetResources())
            .AddInMemoryClients(IdentityServerConfig.GetClients())
            .AddTestUsers(IdentityServerConfig.GetTestUsers())
                .AddDeveloperSigningCredential();
                
    
            }
    
            // 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())
                {
                    app.UseDeveloperExceptionPage();
                }
                //添加identityserver中间件到http管道
                app.UseIdentityServer();
                //app.UseMvc();
            }
        }
    }

    2.获取token

    3.通过刚才获取到的token访问接口

    快速入口:微服务(入门一):netcore安装部署consul

    快速入口: 微服务(入门二):netcore通过consul注册服务

    快速入口: 微服务(入门三):netcore ocelot api网关结合consul服务发现

    快速入口:微服务(入门四):identityServer的简单使用(客户端授权) 

  • 相关阅读:
    [排序算法] 选择排序(2种)
    [排序算法] 交换排序(2种)
    针对Oracle表 列字段的增加、删除、修改以及重命名操作sql
    myelcipse中SVN进行代码更新和提交
    SVN服务器的搭建
    无法变更启动序列号
    mybatis入门学习记录(一)
    java中判断两个字符串是否相等的问题
    xshell如何同时打开多个标签
    设计模式(六) xml方式实现AOP
  • 原文地址:https://www.cnblogs.com/zhengyazhao/p/10769723.html
Copyright © 2020-2023  润新知