Переписать URL в соответствии с атрибутом

#c# #.net #asp.net-core

#c# #.net #asp.net-ядро

Вопрос:

У нас есть ASP.NET Основной веб-API, работающий на .NET 5. У него есть много контроллеров и маршрутов, которые иногда защищены с помощью Authorize атрибута, а иногда они являются общедоступными.

 [ApiController]
[Route("[controller]")]
public class UserController : ControllerBase {

   [HttpGet("me")]
   public IActionResult GetMyPublicInformation()
   {
      // code...
   }

   [HttpGet("me")]
   [Authorize]
   public IActionResult GetMyPrivateInformation() 
   {
      // code...
   }
}
 

Что ж, теперь я хотел бы опубликовать эти маршруты REST через разные HTTP-маршруты, в зависимости от требований авторизации. Например, маршрут GetPublicInformation не требует авторизации. Этот маршрут должен быть доступен в разделе public/user/me . В то время как метод GetMyPrivateInformation требует авторизации и должен быть опубликован под маршрутом secure/user/me .

Конечно, я знаю, что я могу определить маршрут вручную в HttpGet атрибуте (т. Е. [HttpGet("public/user/me") ), Но — кроме того, я ленив — это было бы подвержено ошибкам, потому что у нас есть информация, доступная дважды: один раз с помощью определения маршрута вручную ( HttpGet ) и один раз в Authorize атрибуте. Поэтому, если кто-то забудет изменить один из двух атрибутов, мы получим несоответствие.

Вопрос: Каковы мои варианты автоматизации перезаписи этого URL-адреса (я имею в виду промежуточное программное обеспечение)? Есть ли какие-либо недостатки, которые вы видите при использовании этого подхода? Я боролся с этой идеей, потому что мне не нравится дополнительный волшебный соус в моей кодовой базе. Я предпочитаю эксплицитность, поэтому прямо сейчас я использую ручное присвоение имен маршрутам…

Кстати: я должен взять это на себя из-за ограничений в библиотеке MSAL Microsoft. Я считаю, что мне не нужно этого делать, потому что мы размещаем определение OpenAPI, в котором указаны маршруты, а какие маршруты не авторизованы. В большинстве случаев этого должно быть достаточно.

Комментарии:

1. почему бы не использовать PublicController и PrivateController, где в общедоступном вы можете пометить контроллер как [AllowAnonimous], а частный как [Авторизовать]?

2. Вы могли бы использовать System.reflection и цикл для запуска всего контроллера, и в зависимости от атрибута вы добавляете конфигурацию при запуске для контроллера

3. @alessandro Мне нравится эта идея, и я хотел бы изучить ее подробнее! Это было бы хорошим разделением проблем. Как я об этом не подумал :).

4. @Alen. Тома, это может быть то, что я делаю в промежуточном программном обеспечении, верно?

5. @alessandro вот что это такое 🙂