I am trying to connect to an API using Grails 3.1.4.
In fact the authentication is done and I getthe generated token after sending email and password.
I am trying to send queries after that. However, I can't send the token in header of the http query
String url="www.myurl.com"
CookieHandler.setDefault(new CookieManager(null, CookiePolicy.ACCEPT_ALL))
connection = (HttpURLConnection) new URL(url).openConnection()
connection.setRequestMethod("GET")
connection.setDoOutput(true)
connection.setDoInput(true)
connection.setConnectTimeout(10000)
connection.setRequestProperty("content-Type","application/x-www-form-urlencoded")
connection.setRequestProperty("Set-Cookie","token/"+token)
OutputStream output = connection?.getOutputStream()
output.write(query.getBytes())
It all depends on the authentication mechanism used. If JWT tokens are used, you need to add a http header with the keyword "Authentication" and a value of "Bearer ". Please ask your service supplier which mechanism is used. Usually a 401 statuscode is an indication you are doing something wrong.
Related
Trying to read data of specific envelopes from DocuSign using completely backend java process ... and after some trial and error I've obtained AccessToken with JWT grant but still getting authorization error when asking for actual data :(
Defined new integration key 9xxx7e
User Application: Authorization Code Grant
No secrets added
Service Integration - uploaded public RSA key
Added one Redirect URI (regardless I don't need any)
Manual confirmation of corresponding link : https://account-d.docusign.com/oauth/auth?response_type=code&scope=signature%20impersonation&client_id=9xxx7e&state=123&redirect_uri=https://my.redirect.net/DocuSign ... assuming it is just one-time action
Successfully requested Access Token using java code (using com.docusign:docusign-esign-java:3.10.1)
ApiClient = new ApiClient(ApiClient.DEMO_REST_BASEPATH);
OAuthToken token = apiClient.requestJWTApplicationToken(integrationKeyJwt, scopes, privateKeyFileContent, 3600);
Trying to get envelope data using simple HttpGet
HttpGet request = new HttpGet("https://demo.docusign.net/restapi/v2.1/accounts/6xxx1e/envelopes");
request.addHeader("Content-Type", "application/json");
request.addHeader("Authorization", "Bearer " + token.getAccessToken());
but still got 401 response with content:
{"errorCode":"AUTHORIZATION_INVALID_TOKEN","message":"The access token provided is expired, revoked or malformed. Authentication for System Application failed."}
Please any idea what is wrong? How to obtain correct Access Token?
P.S.: I also tried to get Authorization Code Grant without JWT or implicit grant but no luck without browser tough :(
I would recommend that you print the accessToken you're creating in a file and use in Postman. This will at least help you narrow it down to either the Token generation step or sending the request portion.
Let us know what you find.
Problem was/is with use of apiClient.requestJWTApplicationToken but apiClient.requestJWTUserToken is the way to go
I'm doing a script to update several queries that we use in our project everytime we deploy a sprint.
I'm trying to replicate the same request that I'm testing on Fiddler, that it is working, in the following way:
System.setProperty("sun.net.http.allowRestrictedHeaders", "true");
String host = 'redmine.our-domain.com';
String url = 'http://redmine.our-domain.com/queries/4088';
String REDMINE_SESSION_COOKIE = "_redmine_session=BAh7DkkiDHVzZXJfaWQGOgZFRmkvSSIKY3RpbWUGOwBGbCsHmouFWkkiCmF0aW1lBjsARmwrByk211tJIg9zZXNzaW9uX2lkBjsARkkiJTMzZWJkNmI1MzA4MzZkNmMxNGYwNjY1OWQxMDZjZmU3BjsAVEkiEF9jc3JmX3Rva2VuBjsARkkiMVB3bDlCb0F5NFFCbTd3dmdGWGx0VjdEL05WYjhVRGExdFluQmNMbnFZTHM9BjsARkkiCnF1ZXJ5BjsARnsHOgdpZGkC%2BA86D3Byb2plY3RfaWRpAssBSSIWaXNzdWVzX2luZGV4X3NvcnQGOwBGSSIMaWQ6ZGVzYwY7AEZJIg1wZXJfcGFnZQY7AEZpaUkiFWZqbGVzX2luWGV4X3NvcnQGOwBGSSINZm2sZW5hbWUGOwBG--5c961485290b3c98f38de934b939d25cc01e092f"
String data = "_method=put&authenticity_token=Pwl9BoAy4QBm7wvgFXlsV7D%2FNVb8UDa2tYnBcLnqYLs%3D&query%5Bname%5D=Current+sprint+1.75-test+API+0+0+1&query%5Bvisibility%5D=2query%5Bgroup_by%5D=category&f%5B%5D=status_id&op%5Bstatus_id%5D=o&f%5B%5D6=fixed_version_id&v%5Bfixed_version_id%5D%5B%5D=6030&c%5B%5D=tracker&c%5B%5D=status&c%5B%5D=priority&c%5B%5D=subject&c%5B%5D=assigned_to&c%5B%5D=fixed_version&c%5B%5D=start_date&c%5B%5D=due_date&c%5B%5D=estimated_hours&c%5B%5D=done_ratio&c%5B%5D=parent";
byte[] body = data.getBytes("UTF-8");
HttpURLConnection http = (HttpURLConnection) new URL(url).openConnection();
http.setRequestMethod('POST');
http.setRequestProperty('Cookie', REDMINE_SESSION_COOKIE);
http.setRequestProperty('Content-Type', 'application/x-www-form-urlencoded');
http.setRequestProperty('Host', host);
http.setRequestProperty('Content-Length', "${body.length}");
http.setDoOutput(true);
http.getOutputStream().write(body);
Both, data's authenticity_token and session cookie are fakes, but I'm copy-pasting the Fiddler one.
I'm adding the Host and Content-Length because Fiddler always add them.
Fiddler returns a 302 status that it is right, because Redmine redirects the page.
With the code above I receive a 422 status (Unprocessable Entity) with this message in the body:
Invalid form authenticity token
I've spent 3 days trying to figure out what I'm doing wrong to clone the request. Any clue?
You should rather try to use Redmine's API to acheive your goal, instead of trying to send html form data to controller.
Redmine login form creates also invisible form data fields, which you can see while inspecting with your browser (F12 usually).
One such, hidden field is authenticity token, and it's generated new, every time form is rendered.
Fiddler probably works, because it's performing basic authentication, as described here:
http://www.redmine.org/projects/redmine/wiki/Rest_api#Authentication
So in your code, you must remove part of code trying to mimic form data, and use basic authentication instead, like this:
System.setProperty("sun.net.http.allowRestrictedHeaders", "true");
String host = 'redmine.our-domain.com';
String url = 'http://redmine.our-domain.com/queries/4088';
String auth = Base64.getEncoder().encodeToString((username+":"+password).getBytes(StandardCharsets.UTF_8)); //Java 8 - not sure for 7
HttpURLConnection http = (HttpURLConnection) new URL(url).openConnection();
http.setRequestProperty("Authorization", "Basic "+auth);
http.setRequestMethod('POST');
http.setRequestProperty('Cookie', REDMINE_SESSION_COOKIE);
http.setRequestProperty('Content-Type', 'application/x-www-form-urlencoded');
http.setRequestProperty('Host', host);
http.setRequestProperty('Content-Length', "${body.length}");
http.setDoOutput(true);
http.getOutputStream().write(body);
I am working on a project in which I need, not only to authenticate but also to have the real value of the token.
We have a Spring Boot application with oAuth2.0 Spring Security and the problem is that I am not able to find a method that gives me a valid token every time I call it.
At this moment, I have a post method raw coded in Java, but there must be a Spring Security implementation that does something like the following:
The first time that it is called, it asks for the token and stores it.
The following times checks if the token has expired and, just if it has expired, it asks for a new one.
Where could I find it?
EDIT
There are 2 different Spring Instances in my project: The Authorization server - which is a Cloud Foundry UAA server - and the resource server - which is the one that asks for the token and is coded by me.
The Authorization server uses AuthorizationServerTokenServices in JWT version and when the Resource server gets a token from there, I want it to be kept, not only decoded and used because I need to send it to another server.
Moreover, my application is not a web app, so there is no login page to log in on Facebook and I have to get the token using the Client Credentials Grant Type.
In my case, Single Sign-On is not possible because I have to use it not decoded.
This is my current implementation:
public String obtainAccessToken() throws ClientProtocolException, IOException {
HttpClient httpclient = HttpClients.createDefault();
String userPass64 = new String("User and password");
HttpPost httppost = new HttpPost("localhost:8080/uaa/oauth/token?grant_type=client_credentials");
httppost.setHeader("Content-Type", "application/x-www-form-urlencoded");
httppost.setHeader("Authorization", "Basic " + userPass64);
//Execute and get the response.
HttpResponse response = httpclient.execute(httppost);
String responseBody = EntityUtils.toString(response.getEntity());
ObjectMapper mapper = new ObjectMapper();
TokenMessage tokenMessage = mapper.readValue(responseBody, TokenMessage.class);
return tokenMessage.getAccess_token();
}
From what I have seen is that there are few different ways that Spring security can handle this.
The default way is to have AuthorizationServerTokenServices interface handle it. And with it you can have different ways of storing the token. For example JDBCTokenStore, InMemoryTokenStore and JwtTokenStore. More about this here : http://projects.spring.io/spring-security-oauth/docs/oauth2.html#managing-tokens
But since I do not know what kind of application you are creating, you could maybe develop a single sign on functionality and let Facebook, for example, handle the authentication Token. Quite good tutorial about that with Spring boot can be found here: https://spring.io/guides/tutorials/spring-boot-oauth2/
I am using an API to get some information. At the beginning of each session you need to get a JWT token to be able to send requests to the API. After I've got the token and I try to send a request, I get an error saying I'm unauthorized, which is fair since I did not attach the token in my request. The problem is that the documentation for the API does not explain how to do this, and I haven't been able to find it anywhere else either. How do I do this? I am doing this is Java and is using their own HttpURLConnection. Hopefully you understand what I mean.
Thank you in advanced!
It depends on how the web-service (API) wants to have the token represented.
Common are:
HTTP request headers (problem for XHR requests)
query parameters (bad idea because of caching/logging)
form fields (not universally useable)
URL segment (bad idea because of caching/logging)
certain cookies with the token as value (transparent) or
authentication header (typical)
The Authentication headers as defined in HTTP RFCs are typically be used with the Basic or Digest authorization scheme. In case a string (token) authenticates the bearer of that token, the "Bearer" scheme is used (for example defined for OAuth2 in RFC6750).
You would use
uc.setRequestProperty("Authorization","Bearer " + jwt);
for this.
I am integrating my web app with AppDirect,
for this I created a java rs API using jersey.
When I subscribe to an event, I get a map containing the oauth values (key and secret) to sign my request and an event url to which I issue a sign fetch to.
I am getting those values (oauth and eventurl) as expected.
Now when I try to issue a signed fetch using the library signpost, I use the following code:
OAuthConsumer consumer = new DefaultOAuthConsumer(consumer_key, secret);
// create an HTTP request to a protected resource
URL url = new URL(eventUrl);
HttpURLConnection request = (HttpURLConnection) url.openConnection();
// sign the request
consumer.sign(request);
// send the request
request.connect();
I get this error message:
getResponseMessage: Unauthorized
getresponsecode: 401
I also tried with the following test values:
url = "https://www.appdirect.com/api/integration/v1/events/dummyOrder";
dummyKey = "Dummy";
dummySecret = "secret";
But I got the same result.
Please how can I fix it?
I also tried and adding this:
request.setRequestMethod("GET");
request.setRequestProperty("Authorization", "OAuth");
request.setRequestProperty("Host", "...");
request.setRequestProperty("Content-Type", "application/xml");
request.setRequestProperty("oauth_nonce", oauth_nonce);
request.setRequestProperty("oauth_signature", oauth_signature);
request.setRequestProperty("oauth_signature_method", oauth_signature_method);
request.setRequestProperty("oauth_timestamp", oauth_timestamp);
request.setRequestProperty("oauth_version", oauth_version);
also tried with key:secret in the Authorization property
Here is a behavior of this service when testing via Postman Chrome extension.
If you are using OAuth provider, so you need to get valid api-key for AppDirect and secret.
BTW second screenshot shows you don't need to send an OAuth token to appdirect to https://www.appdirect.com/api/integration/v1/events/dummyOrder, because it authorizes any url.
So, according to your notes, you have to add proper(secret and key) and then AppDirect OAuth server will return you a valid token which you will use when addressing AppDirect's repositories. Or you may send key-secret with each request.