Предисловие
Завершающая работа в цикле по работе с Azure B2C. В этой статье я расскажу о том, как подключить аутентификацию к бэкэнду на .NET Core 3.
Ссылки на связанные посты
- Часть 1: Создание и настройка приложений на Azure AD B2C
- Часть 2: Работа с Identity Framework Experience
- Часть 3: Подключение приложения React
- Часть 4: Подключение приложения React Native
- Часть 5: Подключение и настройка бэкэнда на .NET Core 3
ШАГ 1
В файле Startup.cs в методе ConfigureServices необходимо добавить следующий код:
using Microsoft.AspNetCore.Authentication.JwtBearer;
public void ConfigureServices(IServiceCollection services)
{
// .....
services.AddAuthentication(sharedOptions =>
{
sharedOptions.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(options =>
{
// ClientID вашего приложения Azure AD B2C
options.Audience = "777aaa77a-7a77-7777-bb77-8888888aabc";
// Найти issuer можно во вкладке "Обзор". Для этого нажмите кнопку
// "Конечные точки". В конец поставьте название политики,
// которую вы используете (B2C_1A_signup_signin).
options.Authority = "https://antekesd.b2clogin.com/antekesd.onmicrosoft.com/B2C_1A_signup_signin";
options.TokenValidationParameters = new Microsoft.IdentityModel.Tokens.TokenValidationParameters
{
// Укажите, кто создает токен. Для этого перейдите в ваше приложение на
// Azure AD B2C и во вкладке обзор - скопируйте и замените teanat-id
// на "Идентификатор каталога"
ValidateIssuer = true,
ValidIssuer = "https://antekesd.b2clogin.com/teanat-id/v2.0/"
};
});
// Добавляем политику, по которой будет проверять поступающие запросы
services.AddAuthorization(options =>
{
options.AddPolicy("AuthOnly", policy => policy.RequireAuthenticatedUser());
});
// .....
}
ШАГ 2
В этом же файле, в методе Configure необходимо добавить UseAuthentication и UseAuthorization. Они обязательно должны быть между UseRouting и UseEndpoints, как показано в примере ниже:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
// .....
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller}/{action=Index}/{id?}");
});
// .....
}
ШАГ 3
Теперь все готово, осталось только добавить проверку на контроллер. Для этого в любом контроллере добавьте,
[Authorize(Policy = "AuthOnly")]
как показано в примере ниже:
[Authorize(Policy = "AuthOnly")]
[Route("api/[controller]")]
[ApiController]
public class ClientController : ControllerBase
{
private readonly ClientService _clientService;
public ClientController(ClientService clientService)
{
_clientService = clientService;
}
[HttpGet()]
public async Task<IActionResult> GetClientList()
{
try
{
var result = await _clientService.GetClientsList();
return Ok(result);
}
catch (HttpRequestException httpException)
{
throw httpException;
}
}
}
Теперь, каждый раз когда будет приходить запрос с клиента — бэкэнд будет проверять JWT token. О токенах можно почитать тут.
Пример заголовка запроса:
{
Accept: application/json, text/plain, */*
Accept-Encoding: gzip, deflate, br
Accept-Language: en,ru;q=0.9,en-GB;q=0.8,en-US;q=0.7
Authorization: Bearer jwtIdTokenFromMSAL
Connection: keep-alive
Host: yourhost.azurewebsites.net
Pragma: no-cache
Referer: https://yourhost.azurewebsites.net/
Sec-Fetch-Dest: empty
Sec-Fetch-Mode: cors
Sec-Fetch-Site: same-origin
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.97 Safari/537.36 Edg/83.0.478.45
}
Отправка запроса с одного сервера на другой
Иногда возникает ситуация, когда приложение использует не один бэкэнд. Тогда возникает необходимость отправить запрос с бэка на бэк. Для этого нам нужно создать HTTP клиент и добавить в него токен. Вот как это делается
ШАГ 1
Создаем сервис, который будет слать запросы.
using System.Net.Http;
using System.Net.Http.Headers;
using Microsoft.AspNetCore.Http;
public class ClientService
{
// Создаем HttpClient
HttpClient Client { get; }
public ClientService(HttpClient client, IHttpContextAccessor httpContextAccessor)
{
// Говорим куда слать запрос
client.BaseAddress = new Uri("https://another-server.azurewebsites.net/api/");
string _ContentType = "application/json";
// Говорим что отправлять будем JSON
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue(_ContentType));
// Добавляем JWT Токен
client.DefaultRequestHeaders.Add("Authorization", (string)httpContextAccessor.HttpContext.Request.Headers["Authorization"]);
Client = client;
}
public async Task<string> GetClientsList()
{
// Отправляем запрос
var response = await Client.GetAsync("url-to-another-endpoint");
if (response.StatusCode != HttpStatusCode.OK)
{
return response.StatusCode.ToString();
}
string result = await response.Content.ReadAsStringAsync();
return result;
}
}
ШАГ 2
Добавляем Http client созданному сервису. Для этого нужно в файле Startup.cs добавить следующий код:
public void ConfigureServices(IServiceCollection services)
{
// ...
services.AddHttpClient<ClientService>();
// ...
}
Заключение
Теперь все готово! Вы можете отправлять запрос с клиента на сервер и с сервера на другой сервер.
Спасибо за внимание!