IdentityServer4身份认证授权入门-----客户端凭据、密码模式

时间:2024-01-26 08:58:50

一.简介

IdentityServer4 是为ASP.NET Core 系列量身打造的一款基于 OpenID Connect 和 OAuth 2.0 认证框架

特点:

1.认证服务

2.单点登录登出(SSO)

3.API访问控制

4.联合网关

5.专注于定制

6.成熟的开源系统

7.免费和商业支持

二.简单示例

1.创建ASP.NET Core 3.0 WebAPI项目

执行cmd命令:dotnet new webapi --name IdentityServerCenter

 

 

 2.打开项目

执行cmd命令:code IdentityServerSimple  来打开VS Code

 

 

 3.nuget 安装IdentityServer4

执行Ctrl+Shift+p键 打开Command Palette(命令选项卡)

输入>nuget Package Manager:Add Package

 

 

 `输入IdentityServer4  选择3.1.0

 

 

 安装完成后

 

 

4.执行命令:dotnet restore( 还原依赖项和工具包)

 

 

 5.创建Config类

using System.Collections.Generic;
using IdentityServer4.Models;

namespace IdentityServerCenter{
    public class Config{
        public static IEnumerable<ApiResource> GetResources()
        {
           return new List<ApiResource>{new ApiResource("api","MyAPI")};           
        }

        public static IEnumerable<Client> GetClients()
        {
            return new List<Client>{
            new Client{ClientId="client",AllowedGrantTypes=GrantTypes.ClientCredentials,
            ClientSecrets={new Secret("secret".Sha256())},
            AllowedScopes={"api"}
            }};
        }
    }
}

6.配置Startup类

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.HttpsPolicy;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using IdentityServer4;

namespace IdentityServerCenter
{
    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.AddIdentityServer().AddDeveloperSigningCredential().AddInMemoryApiResources(Config.GetResources()).AddInMemoryClients(Config.GetClients());
            services.AddControllers();
        }

        // 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();
            }

            app.UseHttpsRedirection();

            app.UseRouting();

            app.UseAuthorization();

            app.UseIdentityServer();
 
        }
    }
}

7.配置Progarm类

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;

namespace IdentityServerCenter
{
    public class Program
    {
        public static void Main(string[] args)
        {
            CreateHostBuilder(args).Build().Run();
        }

        public static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)
                .ConfigureWebHostDefaults(webBuilder =>
                {
                    webBuilder.UseStartup<Startup>().UseUrls("http://localhost:5000");
                });
    }
}

8.运行服务端项目:

执行命令:dotnet run

访问地址:http://localhost:5000/.well-known/openid-configuration

 

 

 

三.客户端集成IdentityServer

1.创建项目

执行cmd命令:dotnet new webapi --name ClientCredentialApi

 

 

2. 添加Package

执行命令:dotnet add package Microsoft.AspNetCore.Authentication.JwtBearer

 

 

3.添加IdentityController类

using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;

namespace ClientCredentialApi.Controllers{
    
    [Route("identity")]
    [Authorize]
    public class IdentityController:ControllerBase{
        [HttpGet]
        public IActionResult Get()
        {
            return new JsonResult(new {Msg="Success",Code=200});
        }
    }
}

4.配置Startup类

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.HttpsPolicy;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;

namespace ClientCredentialApi
{
    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.AddControllers();


            services.AddAuthentication("Bearer")
            .AddJwtBearer("Bearer", options =>
            {
                options.Authority = "http://localhost:5000";
                options.RequireHttpsMetadata = false;

                options.Audience = "api";
            });
        }

        // 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();
            }

            app.UseRouting();

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

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllers();
            });
        }
    }
}

5.配置Program类

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;

namespace ClientCredentialApi
{
    public class Program
    {
        public static void Main(string[] args)
        {
            CreateHostBuilder(args).Build().Run();
        }

        public static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)
                .ConfigureWebHostDefaults(webBuilder =>
                {
                    webBuilder.UseStartup<Startup>().UseUrls("http://localhost:5001");
                });
    }
}

6.运行项目

执行命令:dotnet restore  dotnet run 

 

 

 7.输入:http://localhost:5001/identity

401:表示未授权

8.运行服务端和客户端

使用PostMan来获取Token

选择post请求

选择form-data

client_id:client  client_secret:secret grant_type:client_credentials

 

 

 9.通过Token来验证

请求地址:http://localhost:5001/identity

请求方式:get

Headers: key:Authorization  value:Bearer eyJhbGciOiJSUzI1NiIsImtpZCI6Ikt1Ni1YWk9HNWhYYUh3NHdWWGxwSXciLCJ0eXAiOiJhdCtqd3QifQ.eyJuYmYiOjE1ODA4MDYxODIsImV4cCI6MTU4MDgwOTc4MiwiaXNzIjoiaHR0cDovL2xvY2FsaG9zdDo1MDAwIiwiYXVkIjoiYXBpIiwiY2xpZW50X2lkIjoiY2xpZW50Iiwic2NvcGUiOlsiYXBpIl19.A7Mj6xanZfZaAartfFNb3Z6unZRxOGSHgUufcyKFAhL5Ojy5GsXeFlZBTWundXKIC5SILWHoafWrOFvVNcGtH4CxDgUDhlyMpkCRBJyPaAInbLIFqlX9HJLqxzqwUa2Y6qVKtmjBE4WQ9fg4cZSNGviEiqBe2nk2T_U-RLF-y3OMZ6tZblpVZrMYsRiUiyjum3jRJBXRJOw1JaG13OLLrKoEIWX43qRtLZT_5bScqcDJmx4gmcTDeZZZrmsoeT4A7Sr_5hFx_UgwD1edoZiikeFRSvUJZAhLJfuFSR72xMAWSmmqq_H8B3Ed158y0aQb_mHgT8zbQZbHHhIEKD94jg

 

 

 

 四.第三方ClientCredential模式调用

1.创建控制台项目

执行cmd命令:dotnet new console -n ThirdPartyDemo

 

 2.添加IdentityModel包

执行cmd命令:dotnet add package IdentityModel

 

 3.开始测试

  var client = new HttpClient();
            var disco = await client.GetDiscoveryDocumentAsync("http://localhost:5000");
            if (disco.IsError)
            {
                Console.WriteLine(disco.Error);
                return;
            }

            var tokenResponse = await client.RequestClientCredentialsTokenAsync(new ClientCredentialsTokenRequest
            {
                Address = disco.TokenEndpoint,

                ClientId = "client",
                ClientSecret = "secret",
                Scope = "api"
            });

            if (tokenResponse.IsError)
            {
                Console.WriteLine(tokenResponse.Error);
                return;
            }

            Console.WriteLine(tokenResponse.Json);
           

            client.SetBearerToken(tokenResponse.AccessToken);

            var response = await client.GetAsync("http://localhost:5001/identity");
            if (!response.IsSuccessStatusCode)
            {
                Console.WriteLine(response.StatusCode);
            }
            else
            {
                var content = await response.Content.ReadAsStringAsync();
                Console.WriteLine(content);
            }

 

 

 

错误解决:Versioning information could not be retrieved from theNuget package repository. Please try again later.

打开文件:C:\Users\Administrator\.vscode\extensions\jmrog.vscode-nuget-package-manager-1.1.6\out\src\actions\add-methods\fetchPackageVersions.js

 

 

API文档:http://docs.identityserver.io/en/latest/index.html

中文文档:http://www.identityserver.com.cn/

代码地址:https://github.com/CodeInterface/IdentityServerSimple/tree/Simple