У меня есть решение в 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);
}
}
}