Как позвонить в Identity Server 4 с почтальоном для входа - PullRequest
2 голосов
/ 02 октября 2019

У меня есть решение в Visual Studio 'TourManagement', которое содержит 2 проекта ядра .Net. Одним из них является IDP с использованием Identity Server 4, вторым проектом является RESTful API TourManagement, защищенный проектом IDP. Мой вопрос заключается в том, как я могу вызвать Identity Server 4 с помощью Postman для получения токенов и вызвать API-интерфейсы TourManagement Bands, передав эти токены в заголовке, возвращаемом с сервера идентификации в Postman? Мой код ниже.

Класс запуска в проекте 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",
                    }
                }
            };
        }
    }
}

Класс запуска в проекте API TourManagement

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

Контроллер Bands в проекте API Tourmanagement

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


1 Ответ

2 голосов
/ 02 октября 2019

Ключевым моментом является получение токена доступа для доступа к tourmanagementapi с использованием неявного потока в Postman для тестирования.

Первым делом устанавливается AllowAccessTokensViaBrowser на true в конфигурации клиента в функции GetClients, чтобы вы могли передавать токены доступа через канал браузера:

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

Вкл. Почтальон, сделайте следующее:

  1. Введите URL вашего API.
  2. В Authorization Введите, есть раскрывающийся список, выберите OAuth2:

    enter image description here

  3. Выбрав его, вы увидите кнопку с надписью Get Access Token, щелкните ее и введите следующую информацию (на основеВаши коды):

    enter image description here

    Не вводите openid/profile в качестве области, поскольку вы используете Oauth2 в Почтальоне.

  4. Нажмите Request Token, вы увидите новый токен, добавленный с именем TokenName. Наконец, убедитесь, что вы добавили токен в заголовок, затем нажмите Use Token. Токен будет доступен при отправке запроса в качестве заголовка авторизации:

    enter image description here

...