Asp.net-Core

如何使用 Postman 呼叫 Identity Server 4 進行登錄

  • January 6, 2022

我在 Visual Studio ‘TourManagement’ 中有一個解決方案,其中包含 2 個 .Net 核心項目。一個是使用 Identity Server 4 的 IDP,第二個項目是 IDP 項目保護的 TourManagement 的 RESTful API。我的問題是如何使用 Postman 呼叫 Identity Server 4 以獲取令牌並通過在郵遞員身份伺服器返回的標頭中傳遞這些令牌來呼叫 TourManagement Bands API?我的程式碼如下。

IDP項目中的啟動類

using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.DependencyInjection;

namespace Marvin.IDP
{
   public class Startup
   {
       public void ConfigureServices(IServiceCollection services)
       {
           services.AddMvc();

           services.AddIdentityServer()
               .AddDeveloperSigningCredential()
               .AddTestUsers(Config.GetUsers())
               .AddInMemoryApiResources(Config.GetApiResources())
               .AddInMemoryIdentityResources(Config.GetIdentityResources())
               .AddInMemoryClients(Config.GetClients());

           services.AddCors();
       }

       public void Configure(IApplicationBuilder app, IHostingEnvironment env)
       {
           if (env.IsDevelopment())
           {
               app.UseDeveloperExceptionPage();
           }

           app.UseCors(c => c.AllowAnyOrigin().AllowAnyHeader().AllowAnyMethod());

           app.UseIdentityServer();

           app.UseStaticFiles();
           app.UseMvcWithDefaultRoute();
       }         
   }
}

IDP項目中的配置類

using IdentityServer4;
using IdentityServer4.Models;
using IdentityServer4.Test;
using System.Collections.Generic;
using System.Security.Claims;

namespace Marvin.IDP
{
   public static class Config
   {
       public static List<TestUser> GetUsers()
       {
           return new List<TestUser>
           {
               new TestUser
               {
                   SubjectId = "fec0a4d6-5830-4eb8-8024-272bd5d6d2bb",
                   Username = "Jon",
                   Password = "jon123",
                   Claims = new List<Claim>
                   {
                       new Claim("given_name", "Jon"),
                       new Claim("family_name", "Doe"),
                       new Claim("role", "Administrator"),
                   }
               },
               new TestUser
               {
                   SubjectId = "c3b7f625-c07f-4d7d-9be1-ddff8ff93b4d",
                   Username = "Steve",
                   Password = "steve123",
                   Claims = new List<Claim>
                   {
                       new Claim("given_name", "Steve"),
                       new Claim("family_name", "Smith"),
                       new Claim("role", "Tour Manager"),
                   }
               }
           };
       }

       public static List<IdentityResource> GetIdentityResources()
       {
           return new List<IdentityResource>
           {
              new IdentityResources.OpenId(),
              new IdentityResources.Profile(),
              new IdentityResource("roles", "Your role(s)", new []{"role"}),
           };
       }

       internal static IEnumerable<ApiResource> GetApiResources()
       {
           return new[] {
               new ApiResource("tourmanagementapi", "Tour Management API", new[] { "role" })  
           };
       }

       public static List<Client> GetClients()
       {
           return new List<Client>
           {
               new Client
               {
                   ClientName = "Tour Management",
                   ClientId="tourmanagementclient",
                   AllowedGrantTypes = GrantTypes.Implicit,
                   RequireConsent = false,
                   AllowAccessTokensViaBrowser = true,
                   RedirectUris =new List<string>
                   {
                       "https://localhost:4200/signin-oidc",
                       "https://localhost:4200/redirect-silentrenew"
                   },
                   AccessTokenLifetime = 180,
                   PostLogoutRedirectUris = new[]{
                       "https://localhost:4200/" },
                   AllowedScopes = new []
                   {
                       IdentityServerConstants.StandardScopes.OpenId,
                       IdentityServerConstants.StandardScopes.Profile,
                       "roles",
                       "tourmanagementapi",
                   }
               }
           };
       }
   }
}

TourManagement API 項目中的啟動類

using IdentityServer4.AccessTokenValidation;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc.Formatters;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;
using System.Linq;
using TourManagement.API.Authorization;
using TourManagement.API.Services;

namespace TourManagement.API
{
   public class Startup
   {
       public Startup(IConfiguration configuration)
       {
           Configuration = configuration;
       }

       public IConfiguration Configuration { get; }

       public void ConfigureServices(IServiceCollection services)
       {
           services.AddAuthorization();

           services.AddScoped<IAuthorizationHandler, UserMustBeTourManagerRequirementHandler>();

           services.AddMvc(setupAction =>
           {
               setupAction.ReturnHttpNotAcceptable = true;
           })
           .AddJsonOptions(options =>
           {
               options.SerializerSettings.DateParseHandling = DateParseHandling.DateTimeOffset;
               options.SerializerSettings.ContractResolver =
                   new CamelCasePropertyNamesContractResolver();
           });

        
           services.AddCors(options =>
           {
               options.AddPolicy("AllowAllOriginsHeadersAndMethods",
                   builder => builder.AllowAnyOrigin().AllowAnyHeader().AllowAnyMethod());
           });

           var connectionString = Configuration["ConnectionStrings:TourManagementDB"];
           services.AddDbContext<TourManagementContext>(o => o.UseSqlServer(connectionString));

           services.AddScoped<ITourManagementRepository, TourManagementRepository>();

           services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();

           services.AddScoped<IUserInfoService, UserInfoService>();

           services.AddAuthentication(IdentityServerAuthenticationDefaults.AuthenticationScheme)
               .AddIdentityServerAuthentication(options =>
               {
                   options.Authority = "https://localhost:44398";
                   options.ApiName = "tourmanagementapi";
               });

       }

       public void Configure(IApplicationBuilder app, IHostingEnvironment env)
       {
           if (env.IsDevelopment())
           {
               app.UseDeveloperExceptionPage();
           }
           else
           {
               app.UseExceptionHandler(appBuilder =>
               {
                   appBuilder.Run(async context =>
                   {
                       context.Response.StatusCode = 500;
                       await context.Response.WriteAsync("An unexpected fault happened. Try again later.");
                   });
               });
           }

           app.UseCors("AllowAllOriginsHeadersAndMethods");

           app.UseAuthentication();

           app.UseMvc();
       }
   }
}

Tourmanagement API 項目中的樂隊控制器

using AutoMapper;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using System.Collections.Generic;
using System.Threading.Tasks;
using TourManagement.API.Dtos;
using TourManagement.API.Services;

namespace TourManagement.API.Controllers
{
   [Route("api/bands")]
   [Authorize]
   public class BandsController : Controller
   {
       private readonly ITourManagementRepository _tourManagementRepository;

       public BandsController(ITourManagementRepository tourManagementRepository)
       {
           _tourManagementRepository = tourManagementRepository;
       }

       [HttpGet]
       public async Task<IActionResult> GetBands()
       {
           var bandsFromRepo = await _tourManagementRepository.GetBands();

           var bands = Mapper.Map<IEnumerable<Band>>(bandsFromRepo);

           return Ok(bands);
       }
   }
}

關鍵是獲取訪問令牌,以便tourmanagementapi在 Postman 中使用隱式流進行訪問以進行測試。

首先在客戶端配置中設置AllowAccessTokensViaBrowser為function ,以便您可以通過瀏覽器通道傳輸訪問令牌:true``GetClients

new Client
{
.....
   AllowAccessTokensViaBrowser =true,
.....
}

在郵遞員方面,請執行以下操作:

  1. 輸入您的 api 的 URL 。
  2. Authorization類型中,有一個下拉列表,選擇OAuth2

在此處輸入圖像描述 3. 選擇它後,您會注意到一個顯示獲取訪問令牌的按鈕,點擊它並輸入以下資訊(根據您的程式碼):

在此處輸入圖像描述

openid/profile由於您在 Postman 中使用 Oauth2,因此請勿輸入Scope 。 4. 點擊Request Token,您將看到添加了一個名為“TokenName 最後”的新令牌,確保將令牌添加到標題中,然後點擊Use Token。發送請求作為授權標頭時,令牌將可用:

在此處輸入圖像描述

引用自:https://stackoverflow.com/questions/58197304