How can i set credential charset with httpclient 4.3 - character-encoding

AuthPNames.CREDENTIAL_CHARSET is deprecated!?
I don't know how to interpret:
(4.3) use RequestConfig and constructor parameters of
AuthSchemeProviders.
From the documentation.
Can anyone give me an example?

Registry<AuthSchemeProvider> authSchemeRegistry = RegistryBuilder.<AuthSchemeProvider>create()
.register(AuthSchemes.BASIC, new BasicSchemeFactory(Consts.UTF_8))
.register(AuthSchemes.DIGEST, new DigestSchemeFactory(Consts.UTF_8))
.register(AuthSchemes.NTLM, new NTLMSchemeFactory())
.register(AuthSchemes.SPNEGO, new SPNegoSchemeFactory())
.register(AuthSchemes.KERBEROS, new KerberosSchemeFactory())
.build();
CloseableHttpClient client = HttpClients.custom()
.setDefaultAuthSchemeRegistry(authSchemeRegistry)
.build();

Related

How to download file (InputStream) from Microsoft graph APIs?

I am following Graph APIs to download a file from Sharepoint.
I tried this endpoint:
https://graph.microsoft.com/v1.0/drives/{drive_id}/root:/{folder}/{file_name}:/content
And to fetch InputStream using restTemplate:
HttpHeaders httpHeaders = new HttpHeaders();
httpHeaders.setContentType(MediaType.APPLICATION_JSON);
httpHeaders.set(GraphConstant.AUTHORIZATION, TOKEN);
HttpEntity httpEntity = new HttpEntity(httpHeaders);
String downloadEndPoint = DOWNLOAD_FILE_ENDPOINT.replace(GraphConstant.DRIVE_ID,getDriveId(id)).replace("{folder}",folder).replace(GraphConstant.FILE_NAME, URLEncoder.encode(fileName, GraphConstant.UTF_8).replace("+", "%20"));
ResponseEntity<InputStream> responseEntity = restTemplate.exchange(downloadEndPoint,
HttpMethod.GET,
httpEntity,
InputStream.class);
if(responseEntity.getStatusCode().equals(HttpStatus.OK)){
return responseEntity.getBody();
}
responseEntity.getBody() returns null.
What is the return type of Graph Download file API? Any inputs here?
I am using a SpringBoot application and making calls with restTemplate (not using Microsoft SDK to make graph calls).
Changing ResponseEntity to ResponseEntity<byte[]> solved my problem.
ResponseEntity<byte[]> responseEntity = graphRestTemplate.exchange(DOWNLOAD_FILE_ENDPOINT,
HttpMethod.GET,
httpEntity,
byte[].class,
drive_id,
entity_id,
fileName);

Google OAuth2 Java code asking permissions every time

I am using the following with a google-client-secret.json file and trying to run this as just a java application in eclipse. I want to store the permissions so once I accept the permissions it doesn't ask again. Right now it is prompting everytime. After that everything works as expected and writes to my google sheets.
public static Credential authorizeSHEETS() throws IOException, GeneralSecurityException {
File fileIn = new File("src/jg/sos/orders/google-sheets-client-secret.json");
// InputStream in = GoogleAuthorizeUtil.class.getResourceAsStream("src/jg/sos/orders/google-sheets-client-secret.json");
InputStream in = new FileInputStream(fileIn);
GoogleClientSecrets clientSecrets = GoogleClientSecrets.load(JacksonFactory.getDefaultInstance(), new InputStreamReader(in));
List<String> scopes = Arrays.asList(SheetsScopes.SPREADSHEETS);
GoogleAuthorizationCodeFlow flow = new GoogleAuthorizationCodeFlow.Builder(GoogleNetHttpTransport.newTrustedTransport(), JacksonFactory.getDefaultInstance(), clientSecrets, scopes).setDataStoreFactory(new MemoryDataStoreFactory())
.setAccessType("offline").setApprovalPrompt("auto").build();
Credential credential = new AuthorizationCodeInstalledApp(flow, new LocalServerReceiver()).authorize("user");
return credential;
}
Any ideas on how to only have this prompt me the first time for permissions, then the next time I run this it will not?
Thanks for the help!
JJ
So found an answer to this in case anyone comes across. I used a service account instead, and downloaded the json file for it and placed in my project.
Then I just referenced it instead, and saved the token using DataStoreFactory as below:
public static Credential authorizeSHEETS() throws IOException, GeneralSecurityException {
File fileIn = new File("src/jg/sos/orders/google-sheets-client-secret.json");
// InputStream in = GoogleAuthorizeUtil.class.getResourceAsStream("src/jg/sos/orders/google-sheets-client-secret.json");
InputStream in = new FileInputStream(fileIn);
GoogleClientSecrets clientSecrets = GoogleClientSecrets.load(JacksonFactory.getDefaultInstance(), new InputStreamReader(in));
List<String> scopes = Arrays.asList(SheetsScopes.SPREADSHEETS);
FileDataStoreFactory dataStoreFactory = new FileDataStoreFactory(new File("src/jg/sos/orders"));
GoogleAuthorizationCodeFlow flow = new GoogleAuthorizationCodeFlow.Builder(GoogleNetHttpTransport.newTrustedTransport(), JacksonFactory.getDefaultInstance(), clientSecrets, scopes)
.setDataStoreFactory(dataStoreFactory)
.setAccessType("offline").setApprovalPrompt("auto").build();
Credential credential = new AuthorizationCodeInstalledApp(flow, new LocalServerReceiver()).authorize("user");
System.out.println("token" + credential.getAccessToken());
return credential;
}

DocuSign "invalid_grant" on posting jwtToken

I'm trying to achieve "Service Integration Authentication" following the steps here docusign docs and it's doing fine until Requesting the Access Token, where you send the jwt token (which is well formed)
I'm always getting "invalid_grant", and according to that doc, is because some of the claims are invalid. Is there another cause for that error?
All the claims looks good
C#:
//request access token
var client3 = new RestClient("https://" + _host);
var request3 = new RestRequest("/oauth/token", Method.POST);
request3.AddHeader("Content-Type", "application/x-www-form-urlencoded");
request3.AddParameter("grant_type", "urn:ietf:params:oauth:grant-type:jwt-bearer");
var headers = new[]
{
new Claim("alg", "RS256"),
new Claim("typ", "JWT"),
}.ToList();
var claims = new[] {
new Claim("iss", _integrationKey), //<-- integration key
new Claim("sub", OAuthGrant.Sub), //<-- returned from /oauth/userinfo (OK)
new Claim("iat", ToUnixTime(DateTime.Now).ToString(), ClaimValueTypes.Integer64),
new Claim("exp", ToUnixTime(DateTime.Now.AddHours(1)).ToString(), ClaimValueTypes.Integer64),
new Claim("aud", _host), //<-- "account-d.docusign.com"
new Claim("scope", "signature"),
}.ToList();
//build jwt from private key. token decodes just fine from https://jwt.io/
var jwtToken = CreateToken(claims, headers, "private-key.pem", Server.MapPath("/"));
request3.AddParameter("assertion", jwtToken);
System.Diagnostics.Debug.WriteLine("jwtToken:" + jwtToken);
var response = client3.Execute<OAuthToken>(request3);
System.Diagnostics.Debug.WriteLine("response content:" + response.Content); //<-- getting "invalid_grant"
return response.Data;
The jwt token was validated using https://jwt.io/ and decodes just fine.
Is docusign demo sandbox
Thanks in advance
daniel
My assumption is the library which you are using is generating wrong assertion for you. You can check DS SDK as well - ConfigureJwtAuthorizationFlow method in DS SDK, it will help you in generating the Assertion in correct way as expected by DS APIs.

OpenIdConnect HTTP Basic authentication scheme for client authentication

I'm trying to implement an OpenIdConnect login to my .net core 2.0 site.
The IdentityServer I'm trying to use only supports 'client_secret_basic' as token_endpoint_auth_methods.
I configured the application as follows:
services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = "Cookies";
options.DefaultSignInScheme = "Cookies";
options.DefaultChallengeScheme = "oidc";
})
.AddCookie()
.AddOpenIdConnect(options =>
{
options.SignInScheme = "Cookies";
options.Authority = Auhtority;
options.ClientId = ClientID;
options.ClientSecret = ClientSecret;
options.ResponseType = "code";
options.SaveTokens = true;
options.Scope.Add("profile");
options.Scope.Add("rrn");
});
But this seems to post the ClientId and ClientSecret to the body of the request and not using HTTP Basic authentication.
I'm probably missing something obvious, but I can't seem to find how to configure the OpenIdConnect to use client_secret_basic instead of client_secret_post.
Any ideas?
I had the same issue and I finally got it to work using the following options / event hook using System.Net.Http;:
options.Events.OnAuthorizationCodeReceived = context =>
{
context.Backchannel.SetBasicAuthenticationOAuth(context.TokenEndpointRequest.ClientId, context.TokenEndpointRequest.ClientSecret);
return Task.CompletedTask;
};
I got this mostly out of the comments to your question and with the method mentioned there being marked as deprecated with a hint to the new extension method I use.
In 2022 you still can use the IdentityModel nuget.
It has some System.Net.Http extension methods.
https://github.com/IdentityModel/IdentityModel/blob/6f9e050167846724828138ba6ee8b626eb31c669/src/Client/BasicAuthenticationOAuthHeaderValue.cs
Keep in mind you have to remove the client_id/client_secret from the TokenEndpointRequest object.

Signing oAuth with apache HttpRequest for a multipart request

enter code hereI need to send a multipart request to a rest api signed with oAuth
in my pom I'm using
<dependency>
<groupId>oauth.signpost</groupId>
<artifactId>signpost-commonshttp4</artifactId>
<version>1.2.1.1</version>
</dependency>
and I'm using this code to add a multipart form
consumer = new DefaultOAuthConsumer(CONSUMER_KEY, CONSUMER_SECRET);
consumer = new DefaultOAuthConsumer(CONSUMER_KEY, CONSUMER_SECRET);
consumer.setTokenWithSecret("XXXX", "YYYY");
System.out.println("Fetching request token from "
+ REQUEST_TOKEN_ENDPOINT);
PostMethod filePost = new PostMethod("http://..../");
Part[] parts = {
new FilePart("metadata", temp, "application/xml", "UTF8"),
new FilePart("attachment", imageFile, "image/jpeg", null),
};
filePost.setRequestEntity(new MultipartRequestEntity(parts, filePost.getParams()));
HttpClient client = new HttpClient();
int status = client.executeMethod(filePost);
the problem is that to do the consumer.sign(request), to sign the request with oAuth, I need to have an HttpRequest...
so my question is, what can I do to send a multipart POST request with something similar like this using an HttpRequest from apache.
Thanks
Well I reply myself since I solved my problem. I paste here how to do it, hope it may be useful for some body
HttpPost uploadBackgroundPost = new HttpPost ("http://.../");
consumer.sign(uploadBackgroundPost);
MultipartEntity entity = new MultipartEntity (HttpMultipartMode.STRICT);
FileBody tempBody = new FileBody(temp, "application/xml");
FileBody imageBody = new FileBody(imageFile, "image/jpeg");
entity.addPart("metadata", tempBody);
entity.addPart("attachment", imageBody);
uploadBackgroundPost.setEntity(entity);
DefaultHttpClient httpClient = new DefaultHttpClient();
System.out.println(httpClient.execute(uploadBackgroundPost, new BasicResponseHandler()));

Resources