I checked for this behaviour from previous topics raised here, but all of them are either very old or not giving any exact answer, so that's why I'm raising my own question.The method below deletes credential from Jenkins successfuly, but the status code which is returned from Jenkins API is 403, so I had to apply a workaround to deal with this, but I don't like it... it's only a temp solution.Method:
public async Task<bool> deleteCredential(string credentialId){ try { string jenkinsCrumb = await getJenkinsCrumb(); if (string.IsNullOrEmpty(jenkinsCrumb)) { throw new Exception("Unable to retrieve Jenkins crumb."); } string jenkinsToken = await getJenkinsToken(); if (string.IsNullOrEmpty(jenkinsToken)) { throw new Exception("Unable to retrieve Jenkins access token."); } using (var handler = new HttpClientHandler { AllowAutoRedirect=true, UseCookies = true, CookieContainer = new CookieContainer() }) using (var client = new HttpClient(handler)) { string authString = $"{this.jenkinsUser}:{jenkinsToken}"; string base64Auth = Convert.ToBase64String(Encoding.ASCII.GetBytes(authString)); client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", base64Auth); string[] crumbParts = jenkinsCrumb.Split(':'); if (crumbParts.Length == 2) { client.DefaultRequestHeaders.Add(crumbParts[0], crumbParts[1]); } client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/xml")); string encodedCredentialId = Uri.EscapeDataString(credentialId); string deleteUrl = $"{this.jenkinsUrl}/credentials/store/system/domain/_/credential/{encodedCredentialId}/doDelete"; logger.LogInformation($"Deleting credential with ID {credentialId}..."); HttpResponseMessage response = await client.PostAsync(deleteUrl, null); // Check if the initial request was "successful" (even if it's a 403) if (response.StatusCode == HttpStatusCode.Forbidden) { //WORKAROUND: Checking if deletion was successful by performing a HEAD request //Because Jenkins returns 403 even if the credential was deleted //Still under analysis and investigation HttpResponseMessage headResponse = await client.SendAsync(new HttpRequestMessage(HttpMethod.Head, deleteUrl)); if (headResponse.IsSuccessStatusCode || headResponse.StatusCode == HttpStatusCode.NotFound) { logger.LogInformation($"Successfully deleted credential with ID {credentialId} (despite initial 403)"); return true; } else { logger.LogError($"Credential deletion failed to be reflected (HEAD request failed: {headResponse.StatusCode})."); return false; } } else if (response.IsSuccessStatusCode) { logger.LogInformation($"Successfully deleted credential with ID {credentialId}"); return true; } else { logger.LogError($"DELETE request failed. Status: {response.StatusCode}"); return false; } } } catch (Exception ex) { logger.LogError($"Error deleting credential with ID {credentialId}: {ex.Message}"); return false; }}
So the method authenticates via Jenkins token and it also retreives Crumb and that part is fine.But I had to apply that lame logic to check if the credential exists via second header request to determine if the deletion was actually successful or not(after the initial post(delete) request.I read somewhere that the problem might occur because of Jenkins trying to redirect after deletion and not being able to keep the authorization headers, but I'm not really sure is that the case.So does anybody know what is the isssue here and is that expected behaviour?