ASP
.NET Core - Usando o IdentityServer4 - III
![]() |
Neste artigo veremos como usar o IdentityServer4 com a ASP .NET Core. |
Continuando o artigo anterior vamos realizar a implementação da segurança com o IdentitySever4.
Implementando a segurança com o IdentityServer4
Abrindo o projeto Web API em nossa solução vamos instalar o pacote IdentityServer4.AccessTokenValidation neste projeto.
Nota: Essa biblioteca atualmente esta desatualizada e em produção considere substituir essa implementação conforme orienta o artigo : https://leastprivilege.com/2020/07/06/flexible-access-token-validation-in-asp-net-core/
Para isso abra a janela do Package Manager Console e digite : Install-Package IdentityServer4.AccessTokenValidation
A seguir vamos incluir o Middleware Authentication no projeto WebAPI definindo no método ConfigureServices do arquivo Startup o código a seguir :
services.AddAuthentication("Bearer")
.AddIdentityServerAuthentication("Bearer", options =>
{
options.ApiName = "myApi";
options.Authority = "https://localhost:44306";
});
|
Neste código determinamos o nome do recurso - myAPI - que definimos na configuração do projeto IdentityServer, e, informamos a URL na qual o IdentityServer vai ser executado e vai estar atendendo.
Agora inclua no método Configure do arquivo Startup do projeto WebAPI a ativação da autenticação e autorização :
public
void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{ if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } app.UseHttpsRedirection(); app.UseRouting(); app.UseAuthorization(); app.UseAuthorization(); app.UseEndpoints(endpoints => { endpoints.MapControllers(); }); } |
Agora podemos incluir no controlador WeatherController o atributo Authorize de forma a permitir o acesso a este controlador somente aos usuários autenticados.
Estamos assim aplicando a segurança ao endpoint da nossa Web API.
Executando novamente o nosso projeto e fazendo um request GET no POSTMAN para a url localhost:4435/weatherForecast iremos obter o erro 401 Unauthorized:
Assim não temos acesso a API pois agora ela esta protegida.
Vamos então usar ao token de acesso que obtemos no POSTMAN para tentar acessar o endpoint : localhost:44335/weatherforecast
Para isso vamos usar o Header Authorization e escolher o tipo Bearer Token e a seguir copiar e colar o token de acesso e a seguir clicar no botão Send.
Teremos o resultado abaixo onde vemos o status code 200 OK e os dados da API sendo exibidos:
Assim constatamos que nossa API esta segura usando o IdentityServer4 e que usando o token de acesso podemos acessar a API.
A seguir vamos incluir um novo projeto na solução que vai ser o Cliente que vai tentar acessar nossa Web API WeatherForecast.
Criando uma aplicação Web Cliente para acessar a API
Vamos então incluir na solução um no projeto via menu File-> New Project;
Escolhendo o template ASP .NET Core Web Application e informando o nome WebClient;
E usando o template ASP.NET Core Web App (Model-View-Controller) no ambiente do .NET 5.0 :
Ao final teremos dois projetos na solução :
Neste projeto vamos instalar o pacote : Install-Package IdentityModel
O
IdentityModel é uma família de bibliotecas
FOSS para construir clientes
OAuth 2.0 e OpenID Connect.
Em seguida,
precisamos de um serviço que possa se comunicar com o IdentityServer4 e
solicitar um token de acesso com o qual o Projeto
MVC possa acessar os dados da API.
No projeto WebClient vamos criar uma pasta chamada
Services e nesta pasta vamos incluir a interface
TokenService com o código abaixo:
using IdentityModel.Client;
using System.Threading.Tasks; public interface ITokenService
{
Task<TokenResponse> GetToken(string scope);
}
|
Note que TokenResponse é um tipo definido no IdentityModel.
A seguir vamos criar a classe concreta TokenService nesta pasta que implementa esta interface:
using IdentityModel.Client; using System; using System.Net.Http; using System.Threading.Tasks;
namespace WebClient.Services |
Neste código a classe DIscoveryDocumentReponse vem com o pacote que instalamos anteriormente.
No construtor usamos uma instância de HttpClient para para obter os dados do documento do endpoint de configuração do OpenID IdentityServer.
Note que estamos
definindo as URLs aqui, no entanto o ideal e fazer a definição no arquivo
appsettings.json e usar o padrão IOptions
para recuperá-los em tempo de execução.
Neste código também estamos usando os dados do cliente que foi definido na
configuração do IdentityServer :
Address = _discDocument.TokenEndpoint,
ClientId = "cwm.client",
Scope = scope,
ClientSecret = "secret"
Para obter os dados da previsão do tempo vamos criar um nova classe para acomodar os dados.
No Projeto WebClient adicione uma nova classe na pasta Models chamada WeatherModel com o seguinte trecho de código:
using System;
namespace WebClient.Models
{
public class WeatherModel
{
public DateTime Date { get; set; }
public int TemperatureC { get; set; }
public int TemperatureF => 32 + (int)(TemperatureC / 0.5556);
public string Summary { get; set; }
}
}
|
A seguir no controlador HomeController vamos injetar no construtor uma instância do serviço ITokenService:
public class HomeController :
Controller { private readonly ILogger<HomeController> _logger; public ITokenService _tokenService { get; } public HomeController(ILogger<HomeController> logger, ITokenService tokenService) { _logger = logger; _tokenService = tokenService; } ... } |
A seguir inclua um novo método Action neste controlador chamado Weather que vai conversar com a API segura e obter os dados:
public async Task<IActionResult> Weather()
{
var data = new List<WeatherModel>();
var token = await _tokenService.GetToken("myApi.read");
using (var client = new HttpClient())
{
client.SetBearerToken(token.AccessToken);
var result = await client.GetAsync("https://localhost:44335/weatherforecast");
if (result.IsSuccessStatusCode)
{
var model = await result.Content.ReadAsStringAsync();
data = JsonConvert.DeserializeObject<List<WeatherModel>>(model);
return View(data);
}
else
{
throw new Exception("Failed to get Data from API");
}
}
} |
Este código faz o seguinte:
-
Usa o serviço de token e conversa com o IdentityServer4 e recupera um token de
acesso válido;
- Define o token de acesso para o cabeçalho JWT do HttpClient;
- Usa o cliente Http e conversa com a API segura para obter os dados
meteorológicos.
Como estamos adicionando o token JWT, não devemos ter nenhum problema em autenticar o WebClient para usar o WebAPI, certo?
Aqui temos que incluir o pacote Newtonsoft.Json no projeto WebClient via menu Tools-> ..-> Manage Nuget Packages for Solution :
Agora temos que criar a respectiva view Weather.cshtml na pasta /Views/Home para este método Action.
@model List<WeatherModel>
@{
ViewData["Title"] = "Weather";
}
<h1>Weather</h1>
<table class="table table-striped">
@foreach (var weather in Model)
{
<tr>
<td>@weather.Date</td>
<td>@weather.Summary</td>
<td>@weather.TemperatureC</td>
<td>@weather.TemperatureF</td>
</tr>
}
</table>
|
Com a view criada só falta registrar o serviço TokenService no método ConfigureServices da classe Startup:
public void ConfigureServices(IServiceCollection services)
{
services.AddControllersWithViews();
services.AddSingleton<ITokenService, TokenService>();
} |
Ufa, enfim terminamos a autorização do cliente.
Agora, de um Build e execute os 3 projetos na seguinte ordem :
No navegador do projeto WebClient, navegue até ./home/weather, e, você deverá visualizar dos dados obtidos a partir da Web API protegida pelo IdentityServer4:
Desta forma estamos acessando a partir do projeto WebClient os dados do projeto WebAPI.
Pegue o projeto
aqui:
AspnIdentityServer4_Client.zip
"Porque a lei foi
dada por Moisés; a graça e a verdade vieram por Jesus Cristo."
João 1:17
Referências:
ASP .NET Core - Implementando a segurança com
ASP.NET Core MVC - Criando um Dashboard .
C# - Gerando QRCode - Macoratti
ASP .NET - Gerando QRCode com a API do Google
ASP .NET Core 2.1 - Como customizar o Identity
Usando o ASP .NET Core Identity - Macoratti
ASP .NET Core - Apresentando o IdentityServer4
ASP .NET Core 3.1 - Usando Identity de cabo a rabo