如何使用 Postman 调用 Identity Server 4 进行登录

Jul*_*lia 14 asp.net-identity postman openid-connect asp.net-core identityserver4

我在 Visual Studio 'TourManagement' 中有一个解决方案,其中包含 2 个 .Net 核心项目。一个是使用 Identity Server 4 的 IDP,第二个项目是由 IDP 项目保护的 TourManagement 的 RESTful API。我的问题是如何使用 Postman 调用 Identity Server 4 来获取令牌并通过在 postman 中从身份服务器返回的标头中传递这些令牌来调用 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();
        }         
    }
}
Run Code Online (Sandbox Code Playgroud)

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",
                    }
                }
            };
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

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();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

Tourmanagement API 项目中的 Bands Controller

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


Run Code Online (Sandbox Code Playgroud)

Nan*_* Yu 16

关键是获取访问令牌以tourmanagementapi使用 Postman 中的隐式流进行访问以进行测试。

首先在 client config 中设置AllowAccessTokensViaBrowser为function ,以便您可以通过浏览器通道传输访问令牌,:trueGetClients

new Client
{
.....
    AllowAccessTokensViaBrowser =true,
.....
}
Run Code Online (Sandbox Code Playgroud)

在邮递员方面,请执行以下操作:

  1. 输入您的 api 的 URL 。
  2. Authorization类型中,有一个下拉列表,选择OAuth2

    在此处输入图片说明

  3. 选择它后,您会注意到一个按钮,上面写着“获取访问令牌”,单击它并输入以下信息(基于您的代码):

    在此处输入图片说明

    不要openid/profile作为 Scope输入,因为您在 Postman 中使用 Oauth2 。

  4. 单击Request Token,您将看到添加了一个名为“TokenName 最后”的新令牌,确保将令牌添加到标题中,然后单击Use Token。将请求作为授权标头发送时,令牌将可用:

    在此处输入图片说明


axe*_*ter 5

我写了一个关于如何实现这一点的完整分步教程,因为这个主题的答案对我来说还不够好。

与其他响应不同的是,如何自动获取和存储不记名令牌并将其用于测试,而无需执行任何其他操作。非常适合集成测试您的控制器类。

https://medium.com/@rotter.axel/automatically-sign-in-to-identity-server-4-with-postman-and-test-net-core-controller-methods-bc5d8feb199e