Ejemplo n.º 1
0
 /// <summary>
 /// Método construtor
 /// </summary>
 /// <param name="logger">Instância do serviço de log</param>
 /// <param name="requiredPermissions">Permissões requeridas pelo atributo</param>
 /// <param name="provider">Instância do provedor de serviços</param>
 /// <param name="configuration">Instância do container de configurações</param>
 public PermissionAttributeImpl(ILogger <PermissionAttribute> logger, PermissionsAuthorizationRequirement requiredPermissions, IServiceProvider provider, IConfiguration configuration)
 {
     this._logger             = logger;
     this._requiredPermission = requiredPermissions;
     this._provider           = provider;
     this._configuration      = configuration;
 }
Ejemplo n.º 2
0
        /// <summary>
        /// Método que efetua a verificação de permissão de uma identidade considerando o requerimento de permissão informado.
        /// </summary>
        /// <param name="requiredPermission">Requerimento de permissão</param>
        /// <param name="missingPermissions"></param>
        /// <returns>Verdadeiro caso o usuário atenda aos critérios requisitados e falso caso contrário</returns>
        public virtual bool ValidatePermissionByClaims(PermissionsAuthorizationRequirement requiredPermission, out List <string> missingPermissions)
        {
            var result = false;

            if (this.SystemUser.IsRoot())
            {
                this.Logger.LogInformation(Resource.AUTHORIZATION_USER_ISROOT);
                missingPermissions = new List <string>();
                return(true);
            }

            var usrPermissions = this.SystemUser.Permissions.Select(x => x.Value).ToList();

            var ownedPermissions = requiredPermission.Permissions.Where(x => usrPermissions.Contains(x)).ToList();

            missingPermissions = requiredPermission.Permissions.Where(x => !usrPermissions.Contains(x)).ToList();

            result = requiredPermission.ValidationType switch
            {
                PermissionValidationType.RequireOneOf => ownedPermissions.Any(),
                PermissionValidationType.RequireAll => ownedPermissions.Count() == requiredPermission.Permissions.Count(),
                _ => true,
            };
            return(result);
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Método construtor.
        /// </summary>
        /// <param name="method">Método de execução do endpoint</param>
        /// <param name="validationType">Tipo de validação de permissão. Veja <see cref="PermissionValidationType"/></param>
        /// <param name="permissions">Permissões requeridas para autorização</param>
        public PermissionAttribute(Method method, PermissionValidationType validationType, params string[] permissions) : base(typeof(PermissionAttributeImpl))
        {
            var permission = new PermissionsAuthorizationRequirement(method, validationType, permissions);

            Arguments = new[] { permission };
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Método que efetua a validação da autorização de acesso.
        /// </summary>
        /// <param name="context">Contexto de autorização</param>
        /// <param name="requiredPermission">Requerimento de permissão</param>
        public async Task Authorize(AuthorizationFilterContext context, PermissionsAuthorizationRequirement requiredPermission)
        {
            // Se permite anônimo, não é necessário validar nada.
            if (requiredPermission.ValidationType.Equals(PermissionValidationType.Annonymous))
            {
                this.Logger.LogInformation(Resource.AUTHORIZATION_ANNONYMOUS, this.Accessor.HttpContext.Request.Path, this.SystemUser.RemoteIpAddress);
                return;
            }

            this.Logger.LogInformation(Resource.AUTHORIZATION_PROTECTED, this.Accessor.HttpContext.Request.Path, this.SystemUser.RemoteIpAddress);
            // Obtendo configurações da autoridade.
            var settings = this.Configuration.GetIdentityConfigurations();
            // Obtendo token de autorização.
            var token = context.GetAuthorizationToken();

            var tokenDecoder = new JwtSecurityTokenHandler();

            this.Logger.LogInformation(Resource.AUTHORIZATION_VALIDATIND_TOKEN);
            // Verificando se é possível ler o token.
            if (!tokenDecoder.CanReadToken(token))
            {
                this.Logger.LogWarning(Resource.AUTHORIZATION_ERROR_TOKEN_WRONG_FORMAT);
                context.Result = this.Unauthorized();
                return;
            }

            // Fazendo a leitura do token.
            var jwtToken = tokenDecoder.ReadJwtToken(token);

            // Efetuando a validação do token junto a autoridade.
            var result = await jwtToken.ValidateAsync(settings);

            // Se o resultado não é válido, retorna 401.
            if (!result.IsValid)
            {
                this.Logger.LogWarning(Resource.AUTHORIZATION_ERROR_INVALID_TOKEN, result.Status, result.Message);
                context.Result = this.Unauthorized();
                return;
            }

            // Se os dados do usuário são nulos, não possui identidade ou não está autenticado, retorna 401.
            if (result.Principal == null || !result.Principal.Identities.Any() || !result.Principal.Identity.IsAuthenticated)
            {
                this.Logger.LogWarning(Resource.AUTHORIZATION_USER_UNHAUTHORIZED);
                context.Result = this.Unauthorized();
                return;
            }

            this.Logger.LogInformation(Resource.AUTHORIZATION_ADDING_USER_DETAILS);

            // Atualizando dados do usuário.
            try
            {
                await this.UpdateSystemUser(settings, token);

                this.SystemUser.Update();
            }
            catch (IdentityException ex)
            {
                this.Logger.LogError(Resource.ERROR_GET_USERINFO, ex.StatusCode, ex.Message);
                context.Result = this.Unauthorized();
                return;
            }

            // Se é necessária apenas autenticação, não há porquê continuar.
            if (requiredPermission.ValidationType.Equals(PermissionValidationType.RequireAuthenticatedOnly))
            {
                this.Logger.LogInformation(Resource.AUTHORIZATION_USER_AUTHORIZED, this.SystemUser.DisplayName, this.Accessor.HttpContext.Request.Path);
                return;
            }

            // Se há uma permissão padrão, transforme-a em permissão de controller.
            if (requiredPermission.Contains(IdentityConstants.PERMISSION_DEFAULT_TAG))
            {
                var actionDescriptor = context.ActionDescriptor as ControllerActionDescriptor;
                var controllerType   = actionDescriptor.ControllerTypeInfo.AsType();
                requiredPermission.ReplaceDefault(controllerType.GetControllerDefaultPermission());
            }

            var havePermission     = false;
            var missingPermissions = new List <string>();

            switch (settings.PermissionsValidationType)
            {
            case PermissionsValidationType.Claim:
                havePermission = ValidatePermissionByClaims(requiredPermission, out missingPermissions);
                break;

            case PermissionsValidationType.Authority:
                throw new NotImplementedException($"The validation type {settings.PermissionsValidationType} isn't implemented!");
            }

            // Se o usuário não possui permissão para acesso ao serviço, retorna 401.
            if (!havePermission)
            {
                this.LogPermissionErrorMessage(requiredPermission.ValidationType, missingPermissions);
                context.Result = this.Unauthorized();
                return;
            }

            this.Logger.LogInformation(Resource.AUTHORIZATION_USER_AUTHORIZED, this.SystemUser.DisplayName, this.Accessor.HttpContext.Request.Path);
        }