private async Task<KeycloakToken> GetToken() { var keyToken = "token"; KeycloakToken resultToken = null; var tokenSession = _httpContextAccesor.HttpContext.Session.GetString(keyToken); //ToDo: Cambiar por un sessionTokenManager if (string.IsNullOrEmpty(tokenSession)) { resultToken = await _keycloakClient.GetToken(_options.ClientId, _options.ClientSecret); } else { resultToken = JsonConvert.DeserializeObject<KeycloakToken>(tokenSession); if (_options.EnableRefreshToken) { var unixTime = new DateTimeOffset(DateTime.Now); var jwt = new JwtSecurityToken(resultToken.AccessToken); if (jwt.Payload.Exp.HasValue && unixTime.ToUnixTimeSeconds() > jwt.Payload.Exp.Value) { resultToken = await _keycloakClient.GetToken(_options.ClientId, _options.ClientSecret, resultToken.RefreshToken); } } } _httpContextAccesor.HttpContext.Session.SetString(keyToken, JsonConvert.SerializeObject(resultToken)); return resultToken; }
/// <summary> /// Register new user with filled Registration object. /// </summary> /// <param name="userRegistration">Instance of Registration object with filled data.</param> /// <returns></returns> public async Task <KeycloakToken> Registration(Registration userRegistration) { KeycloakToken token = await Login(_clientData.AdminUsername, _clientData.AdminPassword); StringBuilder data = new StringBuilder(); data.Append("{"); data.Append($"\"email\": \"{userRegistration.Email}\","); data.Append($"\"username\": \"{userRegistration.Username}\","); data.Append($"\"firstName\": \"{userRegistration.FirstName}\","); data.Append($"\"lastName\": \"{userRegistration.LastName}\","); data.Append($"\"enabled\": {userRegistration.Enabled},"); data.Append($"\"emailVerified\": {userRegistration.EmailVerified}"); data.Append("}"); using (HttpClient httpClient = new HttpClient()) { using (HttpContent httpContent = new StringContent(data.ToString())) { httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token.AccessToken); httpContent.Headers.ContentType = new MediaTypeHeaderValue("application/json"); var response = await httpClient.PostAsync(KeycloakConstants.userEndpoint, httpContent); string[] locationSegments = response.Headers.Location.AbsoluteUri.Split('/'); string userGuid = locationSegments[locationSegments.Length - 1]; StringBuilder passwordData = new StringBuilder(); passwordData.Append("{"); passwordData.Append($"\"temporary\": {userRegistration.Temporary},"); passwordData.Append($"\"type\": \"password\","); passwordData.Append($"\"value\": \"{userRegistration.Password}\""); passwordData.Append("}"); using (HttpClient resetPasswordClient = new HttpClient()) { using (HttpContent resetPasswordContent = new StringContent(passwordData.ToString())) { resetPasswordClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token.AccessToken); resetPasswordContent.Headers.ContentType = new MediaTypeHeaderValue("application/json"); var resetUrl = _clientData.BaseUrl + KeycloakConstants.userEndpoint + userGuid + "/reset-password"; var response2 = await resetPasswordClient.PutAsync(resetUrl, resetPasswordContent); var login = await Login(userRegistration.Username, userRegistration.Password); return((response2.StatusCode.Equals(HttpStatusCode.NoContent)) ? login : new KeycloakToken()); } } } } }
/// <summary> /// /// </summary> /// <param name="request"></param> public async Task <HttpRequestMessage> AuthenticateAsync(HttpRequestMessage request) { _logger.LogDebug("Starting authenticating the request..."); // prevent unnecessary locks if (_token == null || _token.Expired) { try { _logger.LogTrace("Entering in lock section..."); _semaphore.WaitOne(); _logger.LogTrace("Entered in lock section."); // Ok. Needs a token but we have no one. Obtaining it... if (_token == null) { _logger.LogDebug("No token found. Obtaining it with credentials..."); _token = await _keycloakClient.GetClientTokenAsync( _options.Resource, _options.Credentials.Secret); _logger.LogDebug("Token was been obtained."); } // Access token was died and refresh token is not. So we need one more access token else if (_token.Expired && !_token.RefreshExpired) { _logger.LogDebug("Acces token was died and refresh token is not. Obtaining new access token with refresh..."); _token = await _keycloakClient.GetClientTokenAsync( _options.Resource, _options.Credentials.Secret, _token.RefreshToken); _logger.LogDebug("New acces token was been obtained."); } // Both tokens died. Needs try again from the start else if (_token.Expired && _token.RefreshExpired) { _logger.LogDebug("Access token and refresh token died. Obtaining it with credentials..."); _token = await _keycloakClient.GetClientTokenAsync( _options.Resource, _options.Credentials.Secret); _logger.LogDebug("Token was been obtained."); } } catch (Exception ex) { _logger.LogError(ex, "Error in autoauth mechanism."); _logger.LogDebug("Cleunup the token"); _token = null; throw; } finally { _logger.LogTrace("Releasing the lock..."); _semaphore.Release(); _logger.LogTrace("Lock was been released."); } } _logger.LogDebug("Authenticating the request..."); request.Headers.Authorization = new AuthenticationHeaderValue(_token.TokenType, _token.AccessToken); _logger.LogInformation("Request was been authenticated."); return(request); }