/// <summary> /// /// Esse método é responsável por validar se a API da Aplicação está registrada para usar a API de Autenticação /// Tudo isso ocorrerá através do valor do ClientId informado, que deve ser informado no Request sem a chave criptografada /// Diante do "caminho feliz" o contexto do Request será marcado como válido /// /// </summary> /// <param name="context">É o contexto atual da chamada http na visão do oauth</param> /// <returns>Retorna se o client_id informado é válido (true) ou não (false)</returns> public override Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context) { string clientId = string.Empty; string clientSecret = string.Empty; string symmetricKeyAsBase64 = string.Empty; // Obtém as chaves do contexto de autenticação if (!context.TryGetBasicCredentials(out clientId, out clientSecret)) { context.TryGetFormCredentials(out clientId, out clientSecret); } // Caso não tenha um client_id no contexto da chamada if (context.ClientId == null) { context.SetError("invalid_clientId", "ErrorCode:001 - The client_id is not set"); return(Task.FromResult <object>(null)); } // Busca o client var client = AppClientsStore.FindClient(context.ClientId); // Se não encontrou, então o client_id é inválido if (client == null) { context.SetError("invalid_clientId", "ErrorCode:002 - The client_id is incorrect"); return(Task.FromResult <object>(null)); } // Torna válido o contexto da chamada context.Validated(); return(Task.FromResult <object>(null)); }
/// <summary> /// /// Esse método deverá escrever o Token de Acesso (JWT) de maneira segura, para isso: /// Irá ler o ClientId do ticket de autenticação e buscará na lista de aplicações registradas (AppClientsStore In-Memory) /// Irá decodificar a chave para um array de bytes e após isso irá aplicar uma assinatura HMAC256 que será devolvida para o cliente /// Por fim, irá emitir para o requisitor as informações do JWT /// /// </summary> /// <param name="data">São os dados de autenticação informados</param> /// <returns>O token que identifica o usuário para a aplicação</returns> public string Protect(AuthenticationTicket data) { if (data == null) { throw new ArgumentNullException("data"); } string clientId = data.Properties.Dictionary.ContainsKey(AppClientPropertyKey) ? data.Properties.Dictionary[AppClientPropertyKey] : null; if (string.IsNullOrWhiteSpace(clientId)) { throw new InvalidOperationException("AuthenticationTicket.Properties does not include client"); } AppClient client = AppClientsStore.FindClient(clientId); string symmetricKeyAsBase64 = client.Base64Secret; var keyByteArray = TextEncodings.Base64Url.Decode(symmetricKeyAsBase64); var signingKey = new HmacSigningCredentials(keyByteArray); var token = new JwtSecurityToken(_issuer, clientId, data.Identity.Claims, data.Properties.IssuedUtc.Value.UtcDateTime, data.Properties.ExpiresUtc.Value.UtcDateTime, signingKey); var handler = new JwtSecurityTokenHandler(); var jwt = handler.WriteToken(token); return(jwt); }
public override async Task GrantClientCredentialsAsync(GrantResourceOwnerCredentialsContext context) { var form = context.Request.Form; var clientId = form.First(c => c.Key.Equals("client_id")).Value; if (string.IsNullOrEmpty(clientId)) { context.SetError("ErrorCode:001 - The client_id is not set"); return; } var client = AppClientsStore.FindClient(clientId); if (client == null) { context.SetError("ErrorCode:002 - The client_id is incorrect"); return; } var authVerifyCallback = await _mediator.Send(new AuthenticationUser.Query() { Email = context.UserName, Password = context.Password }); if (authVerifyCallback.IsFailure) { context.SetError("ErrorCode:003 - Invalid user authentication"); return; } var user = authVerifyCallback.Success; var claims = new List <Claim> { new Claim("UserId", user.Id.ToString()), new Claim(ClaimTypes.Email, user.Email), new Claim(ClaimTypes.Name, user.Name), new Claim("aud", clientId), }; context.Validated(claims); await Task.FromResult(0); }