Compartilhar via


Sobre a autorização em microsserviços e aplicativos Web do .NET

Dica

Esse conteúdo é um trecho do eBook, arquitetura de microsserviços do .NET para aplicativos .NET em contêineres, disponível em do .NET Docs ou como um PDF para download gratuito que pode ser lido offline.

miniatura da capa do eBook sobre arquitetura de microsserviços do .NET para aplicativos .NET em contêineres.

Após a autenticação, as APIs Web do ASP.NET Core precisam autorizar o acesso. Esse processo permite que um serviço disponibilize APIs para alguns usuários autenticados, mas não para todos. A autorização pode ser feita com base nas funções dos usuários ou com base na política personalizada, que pode incluir a inspeção de declarações ou outras heurísticas.

Restringir o acesso a uma rota do Core MVC ASP.NET é tão fácil quanto aplicar um atributo Authorize ao método de ação (ou à classe do controlador se todas as ações do controlador exigirem autorização), conforme mostrado no exemplo a seguir:

public class AccountController : Controller
{
    public ActionResult Login()
    {
    }

    [Authorize]
    public ActionResult Logout()
    {
    }
}

Por padrão, adicionar um atributo Authorize sem parâmetros limitará o acesso a usuários autenticados para esse controlador ou ação. Para restringir ainda mais a disponibilidade de uma API somente para usuários específicos, o atributo pode ser expandido para especificar funções ou políticas necessárias que os usuários devem satisfazer.

Implementar autorização baseada em função

ASP.NET Core Identity tem um conceito interno de funções. Além dos usuários, o ASP.NET Core Identity armazena informações sobre diferentes funções usadas pelo aplicativo e mantém o controle de quais usuários são atribuídos a quais funções. Essas atribuições podem ser alteradas programaticamente com o RoleManager tipo que atualiza as funções no armazenamento persistente e o UserManager tipo que pode conceder ou revogar funções dos usuários.

Se você estiver autenticando com tokens de portador JWT, o middleware de autenticação de portador JWT do ASP.NET Core populará as funções de usuário com base nas declarações de função encontradas no token. Para limitar o acesso a uma ação ou controlador MVC a usuários em funções específicas, você pode incluir um parâmetro Roles na anotação Authorize (atributo), conforme mostrado no seguinte fragmento de código:

[Authorize(Roles = "Administrator, PowerUser")]
public class ControlPanelController : Controller
{
    public ActionResult SetTime()
    {
    }

    [Authorize(Roles = "Administrator")]
    public ActionResult ShutDown()
    {
    }
}

Neste exemplo, somente usuários nas funções Administrador ou PowerUser podem acessar APIs no controlador ControlPanel (como executar a ação SetTime). A API ShutDown é ainda mais restrita para permitir o acesso somente aos usuários na função Administrador.

Para exigir que um usuário esteja em várias funções, use vários atributos authorize, conforme mostrado no exemplo a seguir:

[Authorize(Roles = "Administrator, PowerUser")]
[Authorize(Roles = "RemoteEmployee ")]
[Authorize(Policy = "CustomPolicy")]
public ActionResult API1 ()
{
}

Neste exemplo, para chamar a API1, um usuário deve:

  • estar na função Administrator ou PowerUser e

  • estar na função RemoteEmployee e

  • satisfazer a um manipulador personalizado da autorização CustomPolicy.

Implementar autorização baseada em política

As regras de autorização personalizadas também podem ser escritas usando políticas de autorização. Esta seção fornece uma visão geral. Para obter mais informações, consulte o Workshop de Autorização do ASP.NET.

As políticas de autorização personalizadas são registradas no método Startup.ConfigureServices usando o método service.AddAuthorization. Esse método usa um delegado que configura um argumento AuthorizationOptions.

services.AddAuthorization(options =>
{
    options.AddPolicy("AdministratorsOnly", policy =>
        policy.RequireRole("Administrator"));

    options.AddPolicy("EmployeesOnly", policy =>
        policy.RequireClaim("EmployeeNumber"));

    options.AddPolicy("Over21", policy =>
        policy.Requirements.Add(new MinimumAgeRequirement(21)));
});

Conforme mostrado no exemplo, as políticas podem ser associadas a diferentes tipos de requisitos. Depois que as políticas são registradas, elas podem ser aplicadas a uma ação ou controlador passando o nome da política como o argumento Política do atributo Authorize (por exemplo, [Authorize(Policy="EmployeesOnly")]) As políticas podem ter vários requisitos, não apenas um (como mostrado nestes exemplos).

No exemplo anterior, a primeira chamada de AddPolicy é apenas uma maneira alternativa de autorizar por função. Se [Authorize(Policy="AdministratorsOnly")] for aplicado a uma API, somente os usuários na função administrador poderão acessá-la.

A segunda chamada de AddPolicy demonstra uma maneira fácil de exigir que uma determinada declaração esteja presente para o usuário. O método RequireClaim também aceita, opcionalmente, valores esperados para a declaração. Se os valores forem especificados, o requisito será atendido somente se o usuário tiver uma declaração do tipo correto e um dos valores especificados. Se você estiver usando o middleware de autenticação do portador JWT, todas as propriedades JWT estarão disponíveis como declarações de usuário.

A política mais interessante mostrada aqui está no terceiro AddPolicy método, pois usa um requisito de autorização personalizado. Usando requisitos de autorização personalizados, você pode ter muito controle sobre como a autorização é executada. Para que isso funcione, você deve implementar esses tipos:

Se o usuário atender ao requisito, uma chamada para context.Succeed indicará que o usuário está autorizado. Se houver várias maneiras de um usuário atender a um requisito de autorização, vários manipuladores poderão ser criados.

Além de registrar requisitos de política personalizada com chamadas de AddPolicy, você também precisa registrar manipuladores de requisito personalizados por meio da injeção de dependência (services.AddTransient<IAuthorizationHandler, MinimumAgeHandler>()).

Um exemplo de um requisito de autorização personalizado e um manipulador para verificar a idade de um usuário (com base em uma DateOfBirth declaração) está disponível na documentação de autorização do ASP.NET Core.

Autorização e APIs mínimas

ASP.NET dá suporte a APIs mínimas como uma alternativa às APIs baseadas em controlador. As políticas de autorização são a maneira recomendada de configurar a autorização para APIs mínimas, como este exemplo demonstra:

// Program.cs
builder.Services.AddAuthorizationBuilder()
  .AddPolicy("admin_greetings", policy =>
        policy
            .RequireRole("admin")
            .RequireScope("greetings_api"));

// build the app

app.MapGet("/hello", () => "Hello world!")
  .RequireAuthorization("admin_greetings");

Recursos adicionais