So I used answer for this question as my tutorial for token based authentication. But I still have a problem with setting up authorization header.
In my authenticateUser method I tried to set up a bearer header, here's th code
#POST
#Path("/users/authentication")
#Produces("application/json")
#Consumes("application/x-www-form-urlencoded")
public Response getUsers(#FormParam("username") String username,
#FormParam("password") String password){
try{
if(userDao.existUser(username, password)){
User uUser = new User(userDao.getUser(username, password));
uUser.setToken(userDao.issueToken());
uUser.setTokenExpDate();
userDao.updateUser(uUser);
Response response = Response.ok(userDao.getUser(uUser.getId()).getToken())
.header(HttpHeaders.AUTHORIZATION, "Bearer "+userDao.getUser(uUser.getId()).getToken())
.build();
System.out.println(response.getHeaderString(HttpHeaders.AUTHORIZATION));
return response;
}
}catch(Exception e){
return Response.status(Response.Status.UNAUTHORIZED).build();
}
return null;
}
As you can see I'm setting it on response variable and it's there. But once I go to secured method and my AuthenticationFilter activates I find out that the header that i get from requestContext is null. How do I sent token to this header properly in this situation? Here's my full code
The header must be included by the client, not by the server. The general flow is this
1)the client authenticates in your Service with credentials, then the server builds a token and returns it to the client, which stores the token in a secure storage
2)the client performs a request and include the token in the header.
POST /yourservice
Authorization: Bearer thetoken
3)The server checks the header, extracts the token and validate it
Related
I have the following Java Spring REST API method:
#RequestMapping(value = "/login", method = RequestMethod.POST)
public ResponseEntity login(#RequestBody LoginRequest request) {
request.getSession(true);
LoginResponse res = this.authService.login(request);
return new ResponseEntity<>(res, HttpStatus.OK);
}
When called using Postman or from a FireFox browser, I can clearly see the "Set-Cookie" header:
Yet, when I'm using console.log to print the response in Angular, I don't see this header:
This is the REST call in Angular:
this.http.post<Login>(this.url, this.loginRequest, {
headers: AuthService.getHeaders(),
observe: 'response',
withCredentials: true
}).subscribe(
response => {
console.log(response);
});
I did add withCredentials: true and observe: 'response' to the request call as suggested, and I do get the whole response, but without the cookie.
What I want to do is to get a cookie after a successful login, which will be delivered with any request afterwards for authentication in the server.
Thanks for the help!
Seems that browsers do not share the cookies to the client if it's not https. I had to follow this guide in order to serve the application in https mode, and then I was able to see the cookie in the server side.
I'm trying to send a POST request via HttpClient, but server response says "unauthorized" error. How I can get the Bearer Token? I searched for solutions but I don't understand it..
That's my code and I don't know how I get the token for the request...
HttpPost request = new HttpPost("http://domain...");
request.setHeader(HttpHeaders.ACCEPT, "application/json, text/plain, */*");
request.setHeader(HttpHeaders.CONTENT_TYPE, "application/#json");
request.setHeader(HttpHeaders.ACCEPT_LANGUAGE, "de,en-US;q=0.7,en;q=0.3");
request.setHeader(HttpHeaders.ACCEPT_ENCODING, "gzip, deflate, br");
request.setHeader(HttpHeaders.REFERER, "https://domain...");
request.setHeader("DNT", "1");
request.setHeader(HttpHeaders.HOST, "host..");
String authToken = ""; // ... ?
request.setHeader(HttpHeaders.AUTHORIZATION, "Bearer " + authToken);
StringEntity params = new StringEntity("{}");
params.setContentEncoding("UTF-8");
request.setEntity(params);
response = this.getHttpClient().execute(request);
First you have to authenticate user using user name and password(Using HTTP call) then you will have token in response same you can add it to your next POST call in header.
One get/post call is required before your POST call so that you will have token.
Same token can be used for all further call.
Seems you are trying to access some APIs which requires you to first get some access token (bearer token) before to hitting actual API.
Most flows involve two steps as explained below.
Step 1.
Fetch bearer token with basic authentication (below endpoint and parameter are sample value and will be different for your API)
POST /auth
`request.setHeader(HttpHeaders.AUTHORIZATION, "Basic " + authToken);`
Step 2:
Step1 will give you some kind of access token in response. You need to use that to make any subsequent API call.
GET /Student/Mark
`request.setHeader(HttpHeaders.AUTHORIZATION, "Bearer " + authToken);`
You can read more about bearer token at What is the OAuth 2.0 Bearer Token exactly?
Let me know in case you still have any doubts or not able to access your API with the approach I mentioned.
Could anyone explain to me why basic auth is working and the digest isn't working or not showing up in the http headers on the server anyway.
public String login(UserDTO user)
{
ClientConfig clientConfig = new DefaultClientConfig();
clientConfig.getFeatures().put(JSONConfiguration.FEATURE_POJO_MAPPING, Boolean.TRUE);
Client client = Client.create(clientConfig);
// client.addFilter(new HTTPBasicAuthFilter(user.getUsername(), user.getPassword()));
client.addFilter(new HTTPDigestAuthFilter(user.getUsername(), user.getPassword()));
ClientResponse response = client.resource(url + "user/login").accept("application*json").type("application/json").get(ClientResponse.class);
System.out.println(response.toString());
return null;
}
If I use:
client.addFilter(new HTTPBasicAuthFilter(user.getUsername(), user.getPassword()));
I get an authorization header on the server:
USER LOGIN REQUEST
request:uri: /StambomenWebAPI/rest/user/login
method: GET
QueryString: null
Parameters:
Headers:
Name: accept Value: application*json
Name: content-type Value: application/json
Name: authorization Value: Basic QXhsOkxvbA==
Name: user-agent Value: Java/1.7.0_51
Name: host Value: localhost:8084
Name: connection Value: keep-alive
USER AND PASS[XXXXX, XXXXX]
But when I use
client.addFilter(new HTTPDigestAuthFilter(user.getUsername(), user.getPassword()));
I do not get an authorization header field ... :s ?
Using jersey with tomcat v7
My regards and thx in advance for any help
You are not getting an authorization header field because of the digest authentication workflow. See here for more details, but basically:
Client makes a request with no Authorization header
Server responds with a 401 status and a WWW-Authenticate header that looks something like:
Digest realm="testrealm#host.com",
qop="auth,auth-int",
nonce="dcd98b7102dd2f0e8b11d0f600bfb0c093",
opaque="5ccc069c403ebaf9f0171e9517f40e41"
Client repeats the request with the correct Authorization header now that it has digest info from server
From the client side, this is all handled by the Jersey HTTPDigestAuthFilter. So, the filter makes the request without an Authorization header first, and your server should return a 401 status with a WWW-Authenticate header that has the necessary Digest info. Then the filter repeats the request with the correct Authorization header, and your server should authenticate and return the content.
After this initial handshake, the HTTPDigestAuthFilter remembers the necessary digest info, so for all requests after the very first request, the Authorization header will be included.
i've tried to request
https://graph.facebook.com/oauth/authorize?client_id=MY_API_KEY& redirect_uri=http://www.facebook.com/connect/login_success.html&scope=publish_stream,create_event
but i'm getting an error after redirection:
"The requested URL /login.php?login_attempt=1&next=https%3A%2F%2Fwww.facebook...."
where did login.php come from, that is not the redirection page?!
what is the problem at redirection?
thanks!
The redirect_uri should be a URL on your server where facebook will redirect the user after he/she granted you access to his/her protected resources. There you should exchange the request token--the value of the code querystring parameter returned from facebook--for the access_token with a server-side fetch.
The redirect_uri must be on the same domain as the Site URL setting on the Website with Facebook Login in the facebook application setting at https://developers.facebook.com/apps/{your-app-id}/summary/
Redirect the user to the provider
Redirect the user to the provider so he/she can tell the provider that he/she is giving you access to his/hers protected resources which you specified in the scope. After the user gives consent or rejects, the provider will redirect the user to the redirect_uri on your server. To prevent cross site scripting request forgery, you should generate and store a CSRF token and send it with the request.
https://www.facebook.com/dialog/oauth?
client_id={your-app-id}&
redirect_uri=http://your-site.com/after-redirect&
scope=list,of,scopes&
state={a-hard-to-guess-random-csrf-token}
Exchange the request token (code) for access token
In the request handler at http://your-site.com/after-redirect you should check the error and error_message request params. If there are no errors, you should first validate (compare with the stored one) the state CSRF token and if valid, then exchange the code (request token) for an access token by the provider with a server-side fetch. The redirect_uri and grant_type=authorization_code params are required (at least by some providers).
https://graph.facebook.com/oauth/access_token?
code={request-token}&
client_id={your-app-id}&
client_secret={your-app-secret}&
redirect_uri=http://your-site.com/after-redirect&
grant_type=authorization_code
Use the access token to access the user's protected resources
If the token type is bearer you should sent the access_token in the HTTP headers in the form of Authorization: Bearer {access-token}'. See: https://www.rfc-editor.org/rfc/rfc6750#section-2.1
https://graph.facebook.com/me?
fields=name,birthday,photos.limit(10).fields(id, picture)&
access_token={access-token}
Try this way :
public String getOauthUrl(String clientId, String callbackUrl, String scope) {
return "https://graph.facebook.com/oauth/authorize?client_id="
+ clientId + "&display=page&redirect_uri="
+ callbackUrl + "&scope=" + scope;
}
this is the code i'm using:
URL url2 = new URL("https://www.facebook.com/dialog/oauth?client_id=MY_APP_ID&redirect_uri=https://www.facebook.com/connect/login_success.html&scope=publish_stream,create_event");
URLConnection conn = url2.openConnection();
BufferedReader rd = new BufferedReader(new InputStreamReader(conn.getInputStream()));
String test;
test=rd.readLine();
resp.getWriter().println(test);
rd.close();
Requirement: I want to access resources reside in cloud application.
This cloud application provided me following details to access resources through OAuth 1.0 authentication.
OAuth Credentials
Consumer Key
Consumer Secret
OAuth Request URLs
1. Request Token URL
2. Authorise URL
3. Access Token URL
4. API Endpoint URL
I have wrote following java code to get Request Token and Request Token Secret . I store Request Token and Secret in property file for retrieving Access Token.
OAuthAccessor accessor = createOAuthAccessor();
OAuthClient client = new OAuthClient(new HttpClient4());
client.getRequestToken(accessor);
props.setProperty("requestToken", accessor.requestToken);
props.setProperty("tokenSecret", accessor.tokenSecret);
private OAuthAccessor createOAuthAccessor(){
String consumerKey = props.getProperty("consumerKey");
String callbackUrl = null;
String consumerSecret = props.getProperty("consumerSecret");
String reqUrl = props.getProperty("requestUrl");
String authzUrl = props.getProperty("authorizationUrl");
String accessUrl = props.getProperty("accessUrl");
OAuthServiceProvider provider
= new OAuthServiceProvider(reqUrl, authzUrl, accessUrl);
OAuthConsumer consumer
= new OAuthConsumer(callbackUrl, consumerKey,
consumerSecret, provider);
return new OAuthAccessor(consumer);
}
Property file details:
requestToken= generated by service provider
authorizationUrl= Authorise URL provided by cloud application
consumerSecret= Consumer Secret provided by cloud application
accessUrl=Access Token URL provided by cloud application
tokenSecret= generated by service provider
requestUrl= Request Token URL provided by cloud application
consumerKey= Consumer Secret provided by cloud application
appName= API Endpoint URL provided by cloud application
I am able to retrieve Request Token and Request Token Secrete from Service Provider with Request Token URL provided by cloud application.
Then I used generated Request Token and Request Token Secrete to get Access Token by using following code
OAuthAccessor accessor = createOAuthAccessor();
accessor.tokenSecret = props.getProperty("tokenSecret");
OAuthClient client = new OAuthClient(new HttpClient4());
return client.invoke(accessor, "GET", url, params);
After executing above code for retrieving Access token I got following exception
If I pass API Endpoint URL /Resource as value of URL parameter to client.invoke() in above code then I am getting following exception
> <<<<<<<< HTTP response: HTTP/1.1 401 Unauthorized Cache-Control:
> private Content-Type: text/html; charset=utf-8 WWW-Authenticate: OAuth
> Realm="115.248.52.162" X-S: 445759-O1VMAP02 Strict-Transport-Security:
> max-age=31536000 Date: Tue, 18 Jun 2013 06:59:28 GMT Content-Length:
> 142
>
> Exception in thread "main" net.oauth.OAuthProblemException:
> token_rejected oauth_problem_advice: Token RZXHZYCCUMNMZA88032WJFB
> does not match an expected ACCESS token
And if I pass Access Token URL as value of URL parameter in client.invoke() then I am getting following exception
> <<<<<<<< HTTP response: HTTP/1.1 401 Unauthorized Cache-Control:
> private Content-Type: text/html; charset=utf-8 WWW-Authenticate: OAuth
> Realm="49.248.38.202" X-S: 445758-O1VMAP01 Strict-Transport-Security:
> max-age=31536000 Date: Tue, 18 Jun 2013 05:47:30 GMT Content-Length:
> 115
>
> oauth_problem=permission_denied&oauth_problem_advice=The%20consumer%20was%20denied%20access%20to%20this%20resource.
Questions:
Which URL Should I use to get Access Token?
Am I missing any step or setting to retrieve Access token?
Thanks in Advance.
Here is the java code to generate access token. I have integrated my generic application to Jira using OAuth Authentication. Here is the java code to access the using OAuth Authentication. Please include rest-oauth-client-1.0.one-jar jar in your application.
public static String getAccessToken(){
final String baseURI = "http://bmh1060149:8080";
final String consumerKey = "hardcoded-consumer";
final String consumerPrivatekey = "MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDFkPMZQaTqsSXI+bSI65rSVaDzic6WFA3WCZMVMi7lYXJAUdkXo4DgdfvEBO21Bno3bXIoxqS411G8S53I39yhSp7z2vcB76uQQifi0LEaklZfbTnFUXcKCyfwgKPp0tQVA+JZei6hnscbSw8qEItdc69ReZ6SK+3LHhvFUUP1nLhJDsgdPHRXSllgZzqvWAXQupGYZVANpBJuK+KAfiaVXCgA71N9xx/5XTSFi5K+e1T4HVnKAzDasAUt7Mmad+1PE+56Gpa73FLk1Ww+xaAEvss6LehjyWHM5iNswoNYzrNS2k6ZYkDnZxUlbrPDELETbz/n3YgBHGUlyrXi2PBjAgMBAAECggEAAtMctqq6meRofuQbEa4Uq5cv0uuQeZLV086VPMNX6k2nXYYODYl36T2mmNndMC5khvBYpn6Ykk/5yjBmlB2nQOMZPLFPwMZVdJ2Nhm+naJLZC0o7fje49PrN2mFsdoZeI+LHVLIrgoILpLdBAz/zTiW+RvLvMnXQU4wdp4eO6i8J/Jwh0AY8rWsAGkk1mdZDwklPZZiwR3z+DDsDwPxFs8z6cE5rWJd2c/fhAQrHwOXyrQPsGyLHTOqS3BkjtEZrKRUlfdgV76VlThwrE5pAWuO0GPyfK/XCklwcNS1a5XxCOq3uUogWRhCsqUX6pYfAVS6xzX56MGDndQVlp7U5uQKBgQDyTDwhsNTWlmr++FyYrc6liSF9NEMBNDubrfLJH1kaOp590bE8fu3BG0UlkVcueUr05e33Kx1DMSFW72lR4dht1jruWsbFp6LlT3SUtyW2kcSet3fC8gySs2r6NncsZ2XFPoxTkalKpQ1atGoBe3XIKeT8RDZtgoLztQy7/7yANQKBgQDQvSHEKS5SttoFFf4YkUh2QmNX5m7XaDlTLB/3xjnlz8NWOweK1aVysb4t2Tct/SR4ZZ/qZDBlaaj4X9h9nlxxIMoXEyX6Ilc4tyCWBXxn6HFMSa/Rrq662Vzz228cPvW2XGOQWdj7IqwKO9cXgJkI5W84YtMtYrTPLDSjhfpxNwKBgGVCoPq/iSOpN0wZhbE1KiCaP8mwlrQhHSxBtS6CkF1a1DPm97g9n6VNfUdnB1Vf0YipsxrSBOe416MaaRyUUzwMBRLqExo1pelJnIIuTG+RWeeu6zkoqUKCAxpQuttu1uRo8IJYZLTSZ9NZhNfbveyKPa2D4G9B1PJ+3rSO+ztlAoGAZNRHQEMILkpHLBfAgsuC7iUJacdUmVauAiAZXQ1yoDDo0Xl4HjcvUSTMkccQIXXbLREh2w4EVqhgR4G8yIk7bCYDmHvWZ2o5KZtD8VO7EVI1kD0z4Zx4qKcggGbp2AINnMYqDetopX7NDbB0KNUklyiEvf72tUCtyDk5QBgSrqcCgYEAnlg3ByRd/qTFz/darZi9ehT68Cq0CS7/B9YvfnF7YKTAv6J2Hd/i9jGKcc27x6IMi0vf7zrqCyTMq56omiLdu941oWfsOnwffWRBInvrUWTj6yGHOYUtg2z4xESUoFYDeWwe/vX6TugL3oXSX3Sy3KWGlJhn/OmsN2fgajHRip0=";
AtlassianOAuthClient jiraoAuthClient = new AtlassianOAuthClient(consumerKey, consumerPrivatekey, baseURI, "");
TokenSecretVerifierHolder requestToken = jiraoAuthClient.getRequestToken();
String authorizeUrl = jiraoAuthClient.getAuthorizeUrlForToken(requestToken.token);
String token = requestToken.token;
String tokenSecret = requestToken.secret;
System.out.println("Token is " + requestToken.token);
System.out.println("Token secret is " + requestToken.secret);
System.out.println("Retrieved request token. go to " + authorizeUrl);
The above code will give you token, tokenSecret and authorizeUrl. After getting the authorizeUrl, Paste the URL in the browser it will ask for allow and deny options. Allow it to generate the verification code. Ather the url is authorized the access token can be generated from the code below.
URI uri=null;
try {
uri = new URI(authorizeUrl);
} catch (URISyntaxException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if(Desktop.isDesktopSupported()){
Desktop desktop = Desktop.getDesktop();
try {
desktop.browse(uri);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
String verifier = requestToken.verifier;
String accessToken = jiraoAuthClient.swapRequestTokenForAccessToken(token, tokenSecret, verifier);
System.out.println("Access token is : " + accessToken);
return accessToken;
}
If you are also interested in accessing OAuth via command prompt you can also access it via there also. Here are the steps to access it via command prompt.
First create an application link. For that you can refer https://developer.atlassian.com/jiradev/jira-apis/jira-rest-apis/jira-rest-api-tutorials/jira-rest-api-example-oauth-authentication
Download rest-oauth-client-1.0.one-jar.jar and rest-oauth-client-1.0-sources.jar and paste in your local drive. Access the following commands from there.
D:\OAuth Jars>java -jar rest-oauth-client-1.0.one-jar.jar requestToken "Your Jira base url"
Once you execute the above command you will get the Token, Token secret and Retrieved request token.
Token is iJKs7Sq4nI3tK0bTqBYSNNOt9rkwrKK9
Token secret is qimK5FibcAKD5ACbF2aKEPpiBWltgwET
Retrieved request token. go to http://bmh1060149:8080/plugins/servlet/oauth/authorize?oauth_token=iJKs7Sq4nI3tK0bTqBYSNNOt9rkwrKK9
Then you have to invoke the Retrieved request token url through the browser to get the verification code. It will ask you to allow or deny. If you click on allow it will give you verification code.
D:\OAuth Jars>java -jar rest-oauth-client-1.0.one-jar.jar accessToken "Your Jira base url" "iJKs7Sq4nI3tK0bTqBYSNNOt9rkwrKK9" "qimK5FibcAKD5ACbF2aKEPpiBWltgwET" "toYvZB"
This will give you the access token
Access token is : zGBqUzmwobyS0GFXrJMIs18lsAUd51Wb
Once you get the access token you can fetch the data from whatever url you will pass to it.
D:\OAuth Jars>java -jar rest-oauth-client-1.0.one-jar.jar request "zGBqUzmwobyS0GFXrJMIs18lsAUd51Wb" "Your Jira base url/rest/api/2/issue/NWFM-4"
Hope this helps
Without seeing your cloud api documentation, I can only assume they follow the typical oauth dance for authentication - which is:
you get request token from provider (request token url)
using request token, form an auth url (usually points to provider)
redirect user to auth url (authorize url)
user authenticates/authorizes
provider does callback back to you with verifier
using verifier and request token, you exchange for access token (access token url)
now you can use your access token to access the api
So unless you're missing some of these steps, some other things to look at are: correctly signing request, using correct urls for each step, passing correct token at each step.
Also, the request token/secret is usually short lived, while the access token is "usually" much longer and in most cases/systems can be used with multiple api request.