C# - Segurança - Verificando as informações do usuário (.NET Core)
Neste artigo vamos tratar da segurança em aplicações .NET Core, iniciando com a verificação das informações do usuário. |
Para garantir a segurança das aplicações existem vários elementos importantes que você precisa considerar para tornar seus aplicativos seguros.
O principal, claro, é o usuário do aplicativo. O usuário é a pessoa autorizada a acessar a aplicação, mas pode também ser alguém que se passa como um usuário legítimo. Como saber então se esse usuário é confiável ?
Para garantir a segurança de um aplicativo em relação ao usuário temos um processo em duas partes:
Tendo essas
premissas estabelecidas
veremos como obter informações sobre usuários usando os recursos
identity e principals.
Trabalhando com identidades do Windows -
WindowsIdentity
Você pode identificar o usuário que está executando o aplicativo usando os
recursos
identity e principal.
A classe
WindowsIdentity representa um usuário do Windows.
Se você não identificar o usuário com uma conta do Windows, poderá usar outras
classes que implementam a interface IIdentity. Com esta interface você tem acesso ao nome do usuário, informações sobre se o
usuário está autenticado e o tipo de autenticação.
Um principal é um objeto que contém a identidade do
usuário e os roles às quais o usuário pertence. A
interface IPrincipal define a propriedade
Identity, que retorna um objeto
IIdentity, e o método
IsInRole com o qual você pode verificar se o usuário é membro de uma
role específica.
Um
role é uma coleção de usuários que têm as mesmas
permissões de segurança sendo a unidade de administração dos usuários. As
roles podem ser grupos do Windows ou apenas uma
coleção de seqüências de caracteres que você define.
As classes principal disponíveis com o .NET são
WindowsPrincipal, GenericPrincipal e RolePrincipal.
Desde o .NET 4.5, esses tipos principais derivam da classe base
ClaimsPrincipal.
Você também pode criar uma classe principal
personalizada que implemente a interface IPrincipal
ou derive de
ClaimsPrincipal.
Vejamos um exemplo de utilização destes recursos.
Criando o projeto Console
Vamos criar uma aplicação Console App (.NET Core) que fornece acesso ao principal e permite acessar a conta do Windows.
Vamos então criar essa aplicação usando o VS 2017 Community com o nome NetCore_Seguranca.
Para poder usar os recursos precisamos incluir no projeto o pacote System.Security.Principals.Windows via Nuget:
Namespaces usados no projeto:
using System.Collections.Generic;
using System.Security.Claims;
using System.Security.Principal;
using static System.Console;
Com o projeto criado abra o arquivo Program.cs e no método Main inclua o código abaixo:
static void Main(string[] args)
{
WindowsIdentity identity = ExibeInfoIdentity();
WindowsPrincipal principal = ExibeInfoPrincipal(identity);
ExibeInfoClaims(principal.Claims);
ReadLine();
}
|
Definimos 3 métodos que vão retornar informações do identity, do principal e das claims do usuário. Vamos a seguir definir o código em cada um desses métodos.
1- ExibeInfoIdentity
public static WindowsIdentity ExibeInfoIdentity()
{
WindowsIdentity identity = WindowsIdentity.GetCurrent();
if (identity == null)
{
WriteLine("Não é um Windows Identity");
return null;
}
WriteLine($"Tipo de Identity : {identity}");
WriteLine($"Nome : {identity.Name}");
WriteLine($"Autenticado : {identity.IsAuthenticated}");
WriteLine($"Tipo de Autenticação : {identity.AuthenticationType}");
WriteLine($"É usuário Anônimo ? : {identity.IsAnonymous}");
WriteLine($"Token de acesso : " + $"{identity.AccessToken.DangerousGetHandle()}");
WriteLine();
return identity;
}
|
Este método cria um objeto WindowsIdentity invocando o método estático GetCurrent() e acessa suas propriedades exibindo o identitytype, nome da identidade, o tipo e outros valores conforme vemos a seguir:
A classe WindowsIdentity implementa a interface IIdentity que contêm três propriedades :
As demais propriedades exibidas são especificas do tipo de identidade que estamos usando.
O tipo de autenticação mostra o CloudAP porque estou conectado ao sistema usando uma conta do Microsoft Live e o Active Directory vair aparecer no tipo de autenticação, se você estiver usando o Active Directory.
2- ExibeInfoPrincipal(identity)
Um
principal
contém uma identidade e oferece informações adicionais, como as
roles às quais o
usuário pertence.
O recurso Principals implementam a interface
IPrincipal, que oferece o método
IsInRole além de uma propriedade
Identity. Com o Windows, todos os grupos do Windows
dos quais o usuário é membro são mapeados para roles, e,
o método IsInRole está sobrecarregado para aceitar
um identificador de segurança, uma string role ou
um valor da enumeração WindowsBuiltInRole.
No usado verificamos se o usuário pertence às roles internas Users e Administrator:
public static WindowsPrincipal
ExibeInfoPrincipal(WindowsIdentity
identity) { WriteLine("Informação do Principal"); WindowsPrincipal principal = new WindowsPrincipal(identity); if (principal == null) { WriteLine("Não é um Windows Principal"); return null; } WriteLine($"É Usuário ? {principal.IsInRole(WindowsBuiltInRole.User)}"); WriteLine($"É Administrador ? {principal.IsInRole(WindowsBuiltInRole.Administrator)}"); WriteLine(); return principal; } |
Ao executar o código teremos o seguinte resultado :
Isso mostra como podemos acessar facilmente detalhes sobre os usuários atuais e suas roles, e, com essa informação podemos tomar decisões sobre quais ações devem ser permitidas ou negadas.
Todas as classes principal derivam da classe base ClaimsPrincipal, e, dessa forma é possível acessar claims ou declarações dos usuários usando a propriedade Claims de um objeto principal.
É o que faremos no próximo método.
3- ExibeInfoClaims(principal.Claims)
As Claims ou declarações/reivindicações oferecem mais flexibilidade em comparação com as roles.
Uma claim ou
reivindicação é uma declaração feita sobre uma identidade de uma autoridade. Uma
autoridade como o Active Directory ou a
autenticação da conta do Microsoft Live faz reivindicações(claims)
sobre os
usuários - por exemplo, a reivindicação do nome do usuário, reivindicações sobre
a quais grupos o usuário pertence, ou uma reivindicação sobre a idade. Ex: O
usuário já tem 21 anos ou mais e está qualificado a acessar recursos específicos.
No método a seguir estamos acessando uma coleção de
claims(declarações) para exibir informações sobre o assunto, emissor,
tipo de declaração, etc. :
public static void ExibeInfoClaims(IEnumerable<Claim>
claims) { WriteLine("Declarações (Claims) "); foreach (var claim in claims) { WriteLine($"Assunto : {claim.Subject}"); WriteLine($"Emissor : {claim.Issuer}"); WriteLine($"Tipo : {claim.Type}"); WriteLine($"Valor do Tipo : {claim.ValueType}"); WriteLine($"Valor : {claim.Value}"); foreach (var prop in claim.Properties) { WriteLine($"\tProperty: {prop.Key} {prop.Value}"); } WriteLine(); } } |
A seguire
temos um trecho das declarações da conta do Microsoft Live, que fornece
informações sobre o
nome, o ID principal e os identificadores de grupo:
Podemos adicionar declarações a uma identidade do Windows a partir do provedor de declarações.
Podemos também adicionar uma declaração a partir de um programa cliente como uma claim sobre idade:
identity.AddClaim(new Claim("Idade", "25"));
Usar uma declaração como a definida acima é apenas uma questão de confiar ou não na declaração.
Neste tipo de claração o emissor geralmente é o LOCALAUTHORITY e não o AD AUTHORITY(Active Directory) que é mais confiável.
O
WindowsIdentity proveniente da classe base
ClaimsIdentity oferece vários métodos de
verificação para claims ou para recuperar claims. Para testar se uma
reivindicação está disponível, você pode usar o método
HasClaim
método:
bool TemNome = identity.HasClaim (c => c.Type ==
ClaimTypes.Name);
Para recuperar declarações específicas, o método FindAll
precisa de um predicado para definir uma correspondência:
var groupClaims = identity.FindAll (c => c.Type ==
ClaimTypes.GroupSid);
Vimos assim como obter informações de segurança de usuários do Windows usando os recursos do WindowsIdentity.
Pegue o código projeto aqui: NetCore_Seguranca.zip
"Pensai nas coisas que são de cima, e não nas que são
da terra;"
Colossenses 3:2
Veja os
Destaques e novidades do SUPER DVD Visual Basic (sempre atualizado) : clique
e confira !
Quer migrar para o VB .NET ?
Quer aprender C# ??
Quer aprender os conceitos da Programação Orientada a objetos ? Quer aprender o gerar relatórios com o ReportViewer no VS 2013 ? Quer aprender a criar aplicações Web Dinâmicas usando a ASP .NET MVC 5 ? |
Referências:
Super DVD Vídeo Aulas - Vídeo Aula sobre VB .NET, ASP .NET e C#
Super DVD C# - Recursos de aprendizagens e vídeo aulas para C#
ASP .NET Core 2 - MiniCurso Básico - Macoratti
ASP .NET Core - Macoratti
Conceitos - .NET Framework versus .NET Core - Macoratti
ASP .NET Core - Conceitos Básicos - Macoratti.net
ASP .NET Core MVC - CRUD básico com ADO .NET - Macoratti
ASP .NET Core - Implementando a segurança com ... - Macoratti.net
ASP .NET Core - Apresentando Razor Pages - Macoratti
Minicurso ASP .NET Core 2.0 - Autenticação com JWT - I - Macoratti
Minicurso ASP .NET Core 2.0 - Autenticação com JWT - II - Macoratti.net