Esempio n. 1
0
        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;
        }
Esempio n. 2
0
        /// <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);
        }