美文网首页Amazing .NET
IdentityServer4 -ClientCredentia

IdentityServer4 -ClientCredentia

作者: 无为无味无心 | 来源:发表于2018-12-10 17:48 被阅读172次

    0 官方文档 https://identityserver4.readthedocs.io/en/latest/

    1 IdentityServer4 ASP .NET Core 认证中心 搭建

    1.1 新建ASP .NET Core 项目 nuget IdentityServer4
    1.2 新建配置类 IdentityConfig 代码如下 :
    public class IdentityConfig
        {
            /// <summary>
            ///   ApiResource 
            /// </summary>
            /// <returns></returns>
            public static IEnumerable<ApiResource> GetResource()
            {
                return new List<ApiResource>() {
                new ApiResource("UserAPI","OrderAPI"){
                } };
            }
            /// <summary>
            /// Client
            /// </summary>
            /// <returns></returns>
            public static IEnumerable<Client> GetClients()
            {
                var cilentApp = new Client()
                {
                    ClientId = "App1",
                    ClientName = "App",
                    AllowedGrantTypes = new List<string>() {
                        GrantType.ClientCredentials },
                    ClientSecrets = new List<Secret>() {
                        new Secret("Sercrect".Sha256())
                    },
                    AllowedScopes = { "UserAPI"}
                };
                return new List<Client>() {
                        cilentApp
                };
            }
        }
    

    1.3 Startup.cs配置 IdentityServer 代码如下

     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)
            {
                //依赖注入系统中注册IdentityServer
                services.AddIdentityServer()
                //扩展在每次启动时,为令牌签名创建了一个临时密钥。在生成环境需要一个持久化的密钥
                    .AddDeveloperSigningCredential()
                    .AddInMemoryApiResources(IdentityConfig.GetResource())//Api 资源
                    .AddInMemoryClients(IdentityConfig.GetClients());//Api的客户端
                services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
             
            }
    
            // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
            public void Configure(IApplicationBuilder app, IHostingEnvironment env)
            {
                
                app.UseIdentityServer();//使用服务 中间件被添加到HTTP管道中
            }
    
    1.4 启动站点 输入 http://localhost:4000/.well-known/openid-configuration,可以看到授权的终结点等信息。
    222.png
    1.5 获取Token

    POST 传入 client_id 分配的客户端ID,client_secret 分配的客户端密钥,
    grant_type 为认证类型。
    模拟POST请求获取token(1.4中的终结点信息中token_endpoint ) ,请求信息如下:

    ```
    POST /connect/token HTTP/1.1
    Host: localhost:4000
    Cache-Control: no-cache
    Postman-Token: 63d697a1-c044-5f2e-0824-e16c1ed466ce
    Content-Type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW
    
    ------WebKitFormBoundary7MA4YWxkTrZu0gW
    Content-Disposition: form-data; name="client_id"
    
    App1
    ------WebKitFormBoundary7MA4YWxkTrZu0gW
    Content-Disposition: form-data; name="client_secret"
    
    Secret
    ------WebKitFormBoundary7MA4YWxkTrZu0gW
    Content-Disposition: form-data; name="grant_type"
    
    client_credentials
    ------WebKitFormBoundary7MA4YWxkTrZu0gW--
    ```
    

    示例JSON

    {
      "access_token": "eyJhbGciOiJSUzI1NiIsImtpZCI6ImUyM2FkOWMxZmQwZjJjMDU2YTVlN2I3MzU1OWU5MDY1IiwidHlwIjoiSldUIn0.eyJuYmYiOjE1NDQ0MzA3NTAsImV4cCI6MTU0NDQzNDM1MCwiaXNzIjoiaHR0cDovL2xvY2FsaG9zdDo0MDAwIiwiYXVkIjpbImh0dHA6Ly9sb2NhbGhvc3Q6NDAwMC9yZXNvdXJjZXMiLCJVc2VyQVBJIl0sImNsaWVudF9pZCI6IkFwcDEiLCJzY29wZSI6WyJVc2VyQVBJIl19.dyCNlu2ModdXijNYb9kpEPREp1vXxTJrQLjKJrd40PtqnXmHhtgVyg_ynZ4rpytpFFTyw2t9Q-DZqbNGU4FiZsGvbUzq2js87qbMeWinHsFcvjOpVP-PPN12XCiHR7uMcaWIlksgdaOyzn9rGip49Y2qB9EcAQ10a282FtiAd3r-rUaTnEwu2uHZhCaTgcYeuWAgKjslBTR-dmQEM-8QonUK0mCIybiwx2XUNddL4EeYyNUnJnJiC4SmeJwhJGpR-Ayh3S-Kg_IjFiRZTnKfkQEpZcEzbyxf_LAlCIUrEx1OKeZizOsl10h4VyS-5LB-64bISCbLQZFunGHc0shkXw",
      "expires_in": 3600,
      "token_type": "Bearer"
    }
    

    access_token为token 信息,用于访问信息

    1.6 使用Identity 保护API

    新建ASP .NET Core WebAPI项目IdentityServer.UserAPI,
    NUGET 安装 IdentityServer4.AccessTokenValidation
    在默认的 ValuesController 控制器加上特性标签 Authorize.
    代码如下:

    [Route("api/[controller]")]
        [Authorize]
        [ApiController]
        public class ValuesController : ControllerBase
        {
            // GET api/values
            [HttpGet]
            public ActionResult<IEnumerable<string>> Get()
            {
                return new string[] { "value1", "value2" };
            }
        }
    

    然后在Startup.cs中配置IdentityServer,如下:

     public void ConfigureServices(IServiceCollection services)
            {
                services.AddAuthentication("Bearer")
                    .AddIdentityServerAuthentication(c => {
                        c.Authority = "http://localhost:4000";//授权服务器地址
                        c.RequireHttpsMetadata = false;
                        c.ApiName = "UserAPI";//API 名称
                    });
                services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
            }
      public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }
        app.UseAuthentication();//开启授权
        app.UseMvc();
    }
    

    以上配置完成,启动IdentityServer.UserAPI,访问http://localhost:4001/api/values,会返回401状态,未授权。

    使用1.5中的Token来访问API,
    在HTTP请求报文的Head 信息中加入 Authorization头,值为 Bearer 空格 加上 token。
    HTTP信息如下:

    GET /api/values HTTP/1.1
    Host: localhost:4001
    Authorization: Bearer eyJhbGciOiJSUzI1NiIsImtpZCI6ImUyM2FkOWMxZmQwZjJjMDU2YTVlN2I3MzU1OWU5MDY1IiwidHlwIjoiSldUIn0.eyJuYmYiOjE1NDQ0MzA3NTAsImV4cCI6MTU0NDQzNDM1MCwiaXNzIjoiaHR0cDovL2xvY2FsaG9zdDo0MDAwIiwiYXVkIjpbImh0dHA6Ly9sb2NhbGhvc3Q6NDAwMC9yZXNvdXJjZXMiLCJVc2VyQVBJIl0sImNsaWVudF9pZCI6IkFwcDEiLCJzY29wZSI6WyJVc2VyQVBJIl19.dyCNlu2ModdXijNYb9kpEPREp1vXxTJrQLjKJrd40PtqnXmHhtgVyg_ynZ4rpytpFFTyw2t9Q-DZqbNGU4FiZsGvbUzq2js87qbMeWinHsFcvjOpVP-PPN12XCiHR7uMcaWIlksgdaOyzn9rGip49Y2qB9EcAQ10a282FtiAd3r-rUaTnEwu2uHZhCaTgcYeuWAgKjslBTR-dmQEM-8QonUK0mCIybiwx2XUNddL4EeYyNUnJnJiC4SmeJwhJGpR-Ayh3S-Kg_IjFiRZTnKfkQEpZcEzbyxf_LAlCIUrEx1OKeZizOsl10h4VyS-5LB-64bISCbLQZFunGHc0shkXw
    Cache-Control: no-cache
    Postman-Token: 57b580b9-3a85-23ad-6469-41763bc5da05
    
    

    可以看到正常API的返回。

    1.7 C# 调用API

    步骤为
    1 创建Core Cmd 项目 NUGET 安装IdentityModel.
    2 创建授权服务发现实例
    3 创建授权token 获取Client 获取token
    4 HttpClient实例用token 调用API
    代码如下:

    using System;
    using System.Net.Http;
    using IdentityModel;
    using IdentityModel.Client;
    namespace IdentityServer.UseCmd
    {
        class Program
        {
            static void Main(string[] args)
            {
                    //1.1 授权服务发现
                 var disco=DiscoveryClient.GetAsync("http://localhost:4000").Result;
                if (disco.IsError)
                {
                    Console.WriteLine(disco.Error);
                    Console.ReadLine();
                    return;
                }
                //1.2 获取token  
                var tokenClient = new TokenClient
                    (
                    //授权 获取token 节点
                    disco.TokenEndpoint,
                    //ClientId
                    "App1",
                    //ClientSecret
                    "Secret");
                var tokenResponse = tokenClient.RequestClientCredentialsAsync().Result;
                if (tokenResponse.IsError)
                {
                    Console.WriteLine(tokenResponse.Error);
                    return;
                }
                Console.WriteLine(tokenResponse.Json);
                //1.3 调用API
                HttpClient c = new HttpClient();
                //设置授权信息
                c.SetBearerToken(tokenResponse.AccessToken);
                var jsonRe = c.GetAsync("http://localhost:4001/api/values").Result;
                Console.WriteLine(jsonRe.Content.ReadAsStringAsync().Result);
                Console.ReadLine();
            }
        }
    }
    
    

    参考文档:https://identityserver4.readthedocs.io/en/latest/quickstarts/1_client_credentials.html

    相关文章

      网友评论

        本文标题:IdentityServer4 -ClientCredentia

        本文链接:https://www.haomeiwen.com/subject/tosdhqtx.html