Implementação de autenticação de esquema básico estilo Microsoft fácil de usar e muito leve para ASP.NET Core.
Ver no GitHub
.NET Framework 4.6.1 e/ou NetStandard 2.0 em diante
Multi-direcionado: net8.0; líquido7.0; líquido6.0; líquido5.0; netcoreapp3.1; netcoreapp3.0; padrão líquido2.0; net461
Esta biblioteca é publicada no NuGet. Portanto, o pacote NuGet pode ser instalado diretamente no seu projeto se você desejar usá-lo sem fazer alterações personalizadas no código.
Baixe diretamente do link abaixo. Por favor, considere baixar o novo pacote, pois o antigo se tornou obsoleto.
Link do novo pacote - AspNetCore.Authentication.Basic.
Link do pacote antigo - Mihir.AspNetCore.Authentication.Basic.
Ou executando o comando abaixo em seu projeto.
PM> Install-Package AspNetCore.Authentication.Basic
As amostras estão disponíveis no diretório de amostras.
A configuração é bastante simples. Você precisará de conhecimento básico de trabalho do ASP.NET Core 2.0 ou mais recente para começar a usar esta biblioteca.
Existem 2 maneiras diferentes de usar esta biblioteca para realizar seu trabalho. Ambas as formas podem ser misturadas, se necessário.
1] Usando a implementação de IBasicUserValidationService
2] Usando BasicOptions.Events (delegado OnValidateCredentials), que é a mesma abordagem que você encontrará nas bibliotecas de autenticação da Microsoft
Notas:
Requer que o Realm seja definido nas opções se SuppressWWWAuthenticateHeader não estiver definido.
Se uma implementação da interface IBasicUserValidationService for usada, bem como o delegado BasicOptions.Events.OnValidateCredentials também for definido, esse delegado será usado primeiro.
Sempre use o protocolo HTTPS (Certificado SSL) na produção ao usar autenticação básica.
usando AspNetCore.Authentication.Basic;public class Startup{public void ConfigureServices(IServiceCollection services){// Requer que o Realm seja definido nas opções se SuppressWWWAuthenticateHeader não estiver definido.// Se uma implementação da interface IBasicUserValidationService for usada, bem como as opções O delegado .Events.OnValidateCredentials também está definido, então este delegado será usado first.services.AddAuthentication(BasicDefaults.AuthenticationScheme)// O AddBasic abaixo sem parâmetro de tipo exigirá que o delegado options.Events.OnValidateCredentials seja definido.//.AddBasic(options => { options.Realm = "My App"; }) ;// O parâmetro AddBasic com tipo abaixo adicionará o BasicUserValidationService ao contêiner de dependência. .AddBasic<BasicUserValidationService>(options => { options.Realm = "My App"; });services.AddControllers();//// Por padrão, a autenticação não é desafiada para cada solicitação que é o padrão pretendido do ASP.NET Core behavior.//// Portanto, para desafiar a autenticação para todas as solicitações, use a opção FallbackPolicy abaixo.//services.AddAuthorization(options =>//{// options.FallbackPolicy = new AuthorizationPolicyBuilder().RequireAuthenticatedUser().Build();//});}public void Configure(IApplicationBuilder app, IHostingEnvironment env){app.UseHttpsRedirection();// A ordem abaixo da cadeia de pipeline é importante!app.UseRouting();app.UseAuthentication();app.UseAuthorization();app.UseEndpoints(endpoints =>{endpoints.MapControllers();});}}
usando AspNetCore.Authentication.Basic;public class Startup{public void ConfigureServices(IServiceCollection services){// Requer que o Realm seja definido nas opções se SuppressWWWAuthenticateHeader não estiver definido.// Se uma implementação da interface IBasicUserValidationService for usada, bem como as opções O delegado .Events.OnValidateCredentials também está definido, então este delegado será usado first.services.AddAuthentication(BasicDefaults.AuthenticationScheme)// O AddBasic abaixo sem parâmetro de tipo exigirá que o delegado options.Events.OnValidateCredentials seja definido.//.AddBasic(options => { options.Realm = "My App"; }) ;// O parâmetro AddBasic com tipo abaixo adicionará o BasicUserValidationService ao contêiner de dependência. .AddBasic<BasicUserValidationService>(options => { options.Realm = "My App"; });services.AddMvc();//// Por padrão, a autenticação não é desafiada para cada solicitação que é o padrão pretendido do ASP.NET Core behavior.//// Portanto, para desafiar a autenticação para todas as solicitações, use a opção abaixo em vez dos serviços.AddMvc acima ().//services.AddMvc(options => //{// options.Filters.Add(new AuthorizeFilter(new AuthorizationPolicyBuilder().RequireAuthenticatedUser().Build()));//});}public void Configure(IApplicationBuilder app, IHostingEnvironment env){app.UseAuthentication( );app.UseMvc();}}
usando AspNetCore.Authentication.Basic;classe pública BasicUserValidationService: IBasicUserValidationService{privado somente leitura ILogger<BasicUserValidationService> _logger;privado somente leitura IUserRepository _userRepository;public BasicUserValidationService(ILogger<BasicUserValidationService> registrador, IUserRepository userRepository){_logger = logger;_userRepository = userRepository;}public async Task<bool> IsValidAsync(string nome de usuário, string senha){try{// NOTA: NÃO USE ESTA IMPLEMENTAÇÃO. ISTO É APENAS PARA FINS DE DEMO // Escreva sua implementação aqui e retorne verdadeiro ou falso dependendo da validação..var user = await _userRepository.GetUserByUsername(username);var isValid = user != null && user.Password == password;return isValid;}catch (Exceção e){_logger.LogError(e, e.Message);throw;}}}
Obrigatório ser definido se SuppressWWWAuthenticateHeader não estiver definido como verdadeiro. Ele é usado com o cabeçalho de resposta WWW-Authenticate ao desafiar solicitações não autenticadas.
O valor padrão é falso.
Se definido como verdadeiro, NÃO retornará o cabeçalho de resposta WWW-Authenticate ao desafiar solicitações não autenticadas.
Se definido como falso, ele retornará o cabeçalho de resposta WWW-Authenticate ao desafiar solicitações não autenticadas.
O valor padrão é falso.
Se definido como verdadeiro, ele verifica se o filtro AllowAnonymous está na ação do controlador ou nos metadados no endpoint que, se encontrado, não tenta autenticar a solicitação.
O objeto fornecido pelo aplicativo para processar eventos gerados pelo middleware de autenticação básica.
A aplicação pode implementar a interface completamente ou pode criar uma instância de BasicEvents e atribuir delegados apenas aos eventos que deseja processar.
Um delegado atribuído a esta propriedade será invocado imediatamente antes da validação das credenciais.
Você deve fornecer um delegado para essa propriedade para que a autenticação ocorra.
Em seu delegado, você deve chamar context.ValidationSucceeded() que tratará da construção do principal de declarações de autenticação a partir dos detalhes do usuário que serão atribuídos à propriedade context.Principal e chamará context.Success(), ou construir um principal de declarações de autenticação do usuário detalhes e atribua-os à propriedade context.Principal e, finalmente, chame o método context.Success().
Se apenas a propriedade context.Principal for definida sem chamar o método context.Success(), o método Success() será chamado automaticamente.
Um delegado atribuído a esta propriedade será invocado quando a autenticação for bem-sucedida. Não será chamado se o delegado OnValidateCredentials for atribuído.
Ele pode ser usado para adicionar declarações, cabeçalhos, etc. à resposta.
Um delegado atribuído a esta propriedade será invocado quando qualquer exceção inesperada for lançada na biblioteca.
Um delegado atribuído a esta propriedade será invocado antes que um desafio seja enviado de volta ao chamador ao lidar com uma resposta não autorizada.
Use isso apenas se você souber o que está fazendo e se quiser usar uma implementação personalizada. Defina o delegado para lidar com preocupações de desafio 401, se um esquema de autenticação em questão lidar com uma interação de autenticação como parte do seu fluxo de solicitação. (como adicionar um cabeçalho de resposta ou alterar o resultado 401 para 302 de uma página de login ou local de login externo.)
Chame context.Handled() no final para que qualquer lógica padrão para este desafio seja ignorada.
Um delegado atribuído a esta propriedade será invocado se a Autorização falhar e resultar numa resposta Proibida.
Use isso apenas se você souber o que está fazendo e se quiser usar uma implementação personalizada.
Defina o delegado para lidar com Forbid.
Chame context.Handled() no final para que qualquer lógica padrão seja ignorada.
Com o ASP.NET Core, todas as solicitações não são desafiadas para autenticação por padrão. Portanto, não se preocupe se o seu BasicUserValidationService não for atingido quando você não passar os detalhes básicos de autenticação necessários com a solicitação. É um comportamento normal. O ASP.NET Core desafia a autenticação somente quando é especificamente instruído a fazê-lo, decorando o controlador/método com o atributo de filtro [Authorize] ou por algum outro meio.
No entanto, se quiser que todas as solicitações desafiem a autenticação por padrão, dependendo do que você está usando, você pode adicionar a linha de opções abaixo ao método ConfigureServices na classe Startup .
// No ASP.NET Core 3.0 em dianteservices.AddAuthorization(options =>{options.FallbackPolicy = new AuthorizationPolicyBuilder().RequireAuthenticatedUser().Build();});// OU// No ASP.NET Core 2.0 em dianteservices.AddMvc (opções => {options.Filters.Add(new AuthorizeFilter(novo AuthorizationPolicyBuilder().RequireAuthenticatedUser().Build()));});
Se você não estiver usando MVC, mas usando Endpoints no ASP.NET Core 3.0 ou mais recente, poderá adicionar um método de cadeia .RequireAuthorization()
ao mapa de endpoint em Configurar método na classe Startup , conforme mostrado abaixo.
// ASP.NET Core 3.0 em dianteapp.UseEndpoints(endpoints =>{endpoints.MapGet("/", async context =>{await context.Response.WriteAsync("Hello World!");}).RequireAuthorization(); / / NOTA ISSO AQUI!!!! });
O ASP.NET Core oferece suporte à adição de vários esquemas de autenticação aos quais esta biblioteca também oferece suporte. Só preciso usar o método de extensão que leva o nome do esquema como parâmetro. O resto é tudo igual. Isto pode ser alcançado de muitas maneiras diferentes. Abaixo está apenas um exemplo rápido e aproximado.
Observe que o parâmetro do nome do esquema pode ser qualquer string que você desejar.
public void ConfigureServices(serviços IServiceCollection){services.AddTransient<IUserRepository, InMemoryUserRepository>();services.AddAuthentication("Scheme1").AddBasic<BasicUserValidationService>("Scheme1", options => { options.Realm = "My App"; }).AddBasic<BasicUserValidationService_2>("Scheme2", options => { options.Realm = "Meu aplicativo"; }).AddBasic("Scheme3", options => { options.Realm = "Meu aplicativo"; options.Events = new BasicEvents{OnValidateCredentials = async (context) =>{var userRepository = context.HttpContext.RequestServices.GetRequiredService<IUserRepository>();var user = await userRepository.GetUserByUsername(context.Username);var isValid = user ! = null && user.Password == context.Password;if (isValid){context.Response.Headers.Add("ValidationCustomHeader", "From OnValidateCredentials");var Claims = new[]{new Claim("CustomClaimType", "Valor de declaração personalizada - de OnValidateCredentials")});context.ValidationSucceeded (reivindicações); // as declarações são opcionais}else{context.ValidationFailed();}}}});services.AddControllers();services.AddAuthorization(options =>{options.FallbackPolicy = new AuthorizationPolicyBuilder("Scheme1", "Scheme2", " Esquema3").RequireAuthenticatedUser().Build();});}
Versão | Notas |
---|---|
8.0.0 |
|
7.0.0 |
|
6.0.1 |
|
5.1.0 |
|
5.0.0 |
|
3.1.1 |
|
3.1.0 |
|
2.2.0 |
|
RFC 7617: Especificações técnicas para HTTP Básico
Documentação de segurança do ASP.NET Core
aspnet/Segurança
Licença MIT