Identityserver4 ClientCredentials授权

Posted on 2021-01-25 15:23  快醒醒  阅读(101)  评论(0编辑  收藏  举报

转自:https://www.cnblogs.com/hyqq/p/14138024.html;侵删。

Client Credentials

客户端应用不代表用户,客户端应用本身就相当于资源所有者

通常用于机器对机器的通信

客户端也需要身份认证

详细查看https://oauth.net/2/grant-types/client-credentials/

 

安装identityserver4模板

dotnet new -i identityserver4.templates //下载identityserver4模板
dotnet new is4inmem --name Idp //创建一个is4inmem模板的项目 名字为Idp

Config代码

using IdentityServer4.Models;
using System.Collections.Generic;
 
namespace Idp
{
    public static class Config
    {
        public static IEnumerable<IdentityResource> IdentityResources =>
            new IdentityResource[]
            {
                new IdentityResources.OpenId(),
                new IdentityResources.Profile(),
            };
 
        public static IEnumerable<ApiScope> ApiScopes =>
            new ApiScope[]
            {
                new ApiScope("scope1"),
            };
 
        public static IEnumerable<ApiResource> ApiResources =>
            new ApiResource[]
            {
                new ApiResource("api1","#api1")
                {  
                    //!!!重要
                    Scopes = { "scope1"}
                }
            };
 
        public static IEnumerable<Client> Clients =>
            new Client[]
            {
                // m2m client credentials flow client
                new Client
                {
                    ClientId = "console client",
                    ClientName = "Client Credentials Client",
 
                    AllowedGrantTypes = GrantTypes.ClientCredentials,
                    ClientSecrets = { new Secret("511536EF-F270-4058-80CA-1C89C192F69A".Sha256()) },
 
                    AllowedScopes = { "scope1" }
                },
            };
    }
}

startup代码

using IdentityServerHost.Quickstart.UI;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
 
namespace Idp
{
    public class Startup
    {
        public IWebHostEnvironment Environment { get; }
        public IConfiguration Configuration { get; }
 
        public Startup(IWebHostEnvironment environment, IConfiguration configuration)
        {
            Environment = environment;
            Configuration = configuration;
        }
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddControllersWithViews();
            //注册IdentityServer
            var builder = services.AddIdentityServer(options =>
            {
                options.Events.RaiseErrorEvents = true;
                options.Events.RaiseInformationEvents = true;
                options.Events.RaiseFailureEvents = true;
                options.Events.RaiseSuccessEvents = true;
 
                // see https://identityserver4.readthedocs.io/en/latest/topics/resources.html
                options.EmitStaticAudienceClaim = true;
            })
                //用户
                .AddTestUsers(TestUsers.Users);
 
            // in-memory, code config
            builder.AddInMemoryIdentityResources(Config.IdentityResources);
            builder.AddInMemoryApiScopes(Config.ApiScopes);
            //添加API资源
            builder.AddInMemoryApiResources(Config.ApiResources);
            builder.AddInMemoryClients(Config.Clients);
            // not recommended for production - you need to store your key material somewhere secure
            builder.AddDeveloperSigningCredential();
        }
 
        public void Configure(IApplicationBuilder app)
        {
            if (Environment.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            app.UseStaticFiles();
            app.UseRouting();
            app.UseIdentityServer();
            app.UseAuthorization();
            app.UseEndpoints(endpoints =>
            {
                endpoints.MapDefaultControllerRoute();
            });
        }
    }
}

创建一个控制台应用 consoleclient

安装identitymodel库

Program代码

using IdentityModel.Client;
using System;
using System.Net.Http;
using System.Threading.Tasks;
 
namespace consoleclient
{
    class Program
    {
        static async Task Main(string[] args)
        {
            //
            var client = new HttpClient();
            var disco = await client.GetDiscoveryDocumentAsync("http://localhost:5001");
            if (disco.IsError)
            {
                Console.WriteLine(disco.Error);
                return;
            }
            //请求accesstoken
            var tokenResponse = await client.RequestClientCredentialsTokenAsync(new ClientCredentialsTokenRequest
            {
                Address = disco.TokenEndpoint,
                ClientId = "console client",
                ClientSecret = "511536EF-F270-4058-80CA-1C89C192F69A",
                Scope = "scope1"
            });
            if (tokenResponse.IsError)
            {
                Console.WriteLine(tokenResponse.Error);
                return;
            }
            Console.ReadKey();
        }
    }
}

启动2个项目 监听tokenresponse

创建空的web项目 添加Controller文件夹 添加IdentityController控制器

添加Microsoft.AspNetCore.Authentication.JwtBearer库

IdentityController代码

using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using System.Linq;
 
namespace scope1
{
    [Route("api/[controller]")]
    [ApiController]
    [Authorize]
    public class IdentityController : ControllerBase
    {
        [HttpGet]
        public IActionResult Get()
        {
            return new JsonResult(from c in User.Claims select new { c.Type,c.Value} );
        }
    }
}

Startup代码

using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
 
namespace scope1
{
    public class Startup
    {
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddControllers();
            services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
        .AddJwtBearer(options =>
        {
            //IdentityServer地址
            options.Authority = "http://localhost:5000";
            //对应Idp中ApiResource的Name
            options.Audience = "api1";
            //不使用https
            options.RequireHttpsMetadata = false;
        });
        }
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            app.UseRouting();
            //身份验证
            app.UseAuthentication();
            //授权
            app.UseAuthorization();
            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllers();
            });
        }
    }
}

继续修改consoleclient项目的Program.cs

using IdentityModel.Client;
using Newtonsoft.Json.Linq;
using System;
using System.Net.Http;
using System.Threading.Tasks;
 
namespace consoleclient
{
    class Program
    {
        static async Task Main(string[] args)
        {
            var client = new HttpClient();
            var disco = await client.GetDiscoveryDocumentAsync("http://localhost:5000");
            if (!disco.IsError)
            {
                //请求accesstoken
                var tokenResponse = await client.RequestClientCredentialsTokenAsync(new ClientCredentialsTokenRequest
                {
                    Address = disco.TokenEndpoint,
                    ClientId = "console client",
                    ClientSecret = "511536EF-F270-4058-80CA-1C89C192F69A",
                    Scope = "scope1"
                });
                if (!tokenResponse.IsError)
                {
                    //使用请求accesstoken访问被保护的资源
                    var apiClient = new HttpClient();
                    apiClient.SetBearerToken(tokenResponse.AccessToken);
                    var response = await apiClient.GetAsync("http://localhost:5001/api/Identity");
                    var content = await response.Content.ReadAsStringAsync();
                    Console.WriteLine(JArray.Parse(content));
                }
            }
        }
    }
}

启动程序

打印结果

 

Copyright © 2024 快醒醒
Powered by .NET 9.0 on Kubernetes