Authorization failure with AWS API Gateway - angularjs

I have integrated AWS API Gateway with AWS Cognito User pool. The following curl command works.
curl -X PUT -H "Authorization:<id token>" -d <json data> <https url>
However, authorization fails with the following Angularjs $http.put.
AWS cloudwatch logs show "user is unauthorized"
$http.defaults.headers.common['Authorization'] = token
$http.put('https://<url>', <json data> )
.then(function (data, status, headers, config) {
console.log('success')
}, function (data, status, headers, config) {
console.log('failure')
});
How should the authorization token be set with $http.put?

I think what you want to do is to set the header for the request as the second argument in the $http.put(<url>, options)....
So in your case, your code should look like this:
var options = {headers: {
'Authorization': token,
'Content-Type': 'application/json'
}
};
$http.put('https://<url>', <json data>, options);
You can check documentation here to learn more about different ways of invoking the $http.X methods.
I hope this helps.

Related

login flow with AngularJS and JWT

In my webapp, when the main page is requested by a non logged in user, I display a login page (containing only a login form). Then the user inputs its userid and pwd and an AngularJS controller issues a HTTP POST request to /connection which returns a JWT autentification token in case of accepted credentials.
Then I'd like the AngularJS controller to issue a GET on / passing the token in the header so the next loaded page is the main webapp page which the connected user can start to play with.
How do I acheive that with AngularJS. Should I use $document.location.href ? If yes how can the token set into the HTTP header ?
Thanks
You can Do it in 2 ways:
1-Use Custom Header for all the initiated Requests (doesn't matter get, post, etc..) and in here our friends posted a lot of different Approaches.
AngularJS $http custom header for all requests
2-Overriding the Header for the Request like this:
$http.get(/*The Call URL*/'http://myawesomeurl/jsondata',/*Configuration Object*/
{/*Overriding the header of the request*/
headers: {
'Content-Type': 'application/json',//request content type
'Authorization': 'token d2VudHdvcnRobWFuOkNoYW5nZV9tZQ=='//Token parameter
//,'myAwesomeHeaderParam':'the header is all yours, add or remove anything'
}
})
.success(function (data, status, headers, config) {
console.log(data);//Received data
})
.error(function (data, status, headers, config) {
console.log('Error Status:'+status);
console.log(data);//Any Server Response values in the case of error
});
//Another Way for initiating the request just for your info
/* var reqInfo = {
method: 'GET',//POST, PUT
url: 'http://myawesomeurl/jsondata',
headers: {
'Content-Type': 'application/json',//request content type (can be not used)
'Authorization': 'token d2VudHdvcnRobWFuOkNoYW5nZV9tZQ=='//Token parameter
}
//,data:{'myAwesomeParameter':'in case of post or put, etc..'} //Request body
};
$http(reqInfo).success(....*/
And you can know more about the Configuration Object here

jhipster oauth : How can i get the token via CURL

I am trying to use the jhipster to create a new project with the oauth2 authentication. The project example works fine, I can login with the angularjs interface. However when I try to retrieve an access_token using CURL in the command line, I get response as :
"error":"Unauthorized","message":"Bad credentials"
Can someone help me on how to use curl to get the access_token?
Here you go!
curl http://127.0.0.1:8080/oauth/token --request POST --insecure --data
"username=[xxx]&password=[yyy]&grant_type=password&scope=read%20write&
client_secret=[your app secret]&client_id=[your app id] " -H
"Authorization:Basic [base64 of your appid:appsecrt]"
uncomment cors in application.yml inside jhipster
cors: #By default CORS are not enabled. Uncomment to enable.
allowed-origins: "*"
allowed-methods: GET, PUT, POST, DELETE, OPTIONS
allowed-headers: "*"
exposed-headers:
allow-credentials: true
max-age: 1800
To access REST API with Oauth2 authentication in ionic you must first get the token in ionic app by
$http({
method: "post",
url: "http://192.168.0.4:8085/[Your app name]/oauth/token",
data: "username=admin&password=admin&grant_type=password&scope=read write&client_secret=my-secret-token-to-change-in-production&client_id=auth2Sconnectapp",
withCredentials: true,
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'Accept': 'application/json',
'Authorization': 'Basic ' + 'YXV0aDJTY29ubmVjdGFwcDpteS1zZWNyZXQtdG9rZW4tdG8tY2hhbmdlLWluLXByb2R1Y3Rpb24='
}
})
.success(function(data) {
alert("success: " + data);
})
.error(function(data, status) {
alert("ERROR: " + data);
});
here "YXV0aDJTY29ubmVjdGFwcDpteS1zZWNyZXQtdG9rZW4tdG8tY2hhbmdlLWluLXByb2R1Y3Rpb24=" is equal to (clientId + ":" + clientSecret)--all base64-encoded
you can use https://www.base64encode.org/ to verify or recreate it for yourself
the aboue $http if successful will give you this JSON which contains token and it's expiry time
{
"access_token": "2ce14f67-e91b-411e-89fa-8169e11a1c04",
"token_type": "bearer",
"refresh_token": "37baee3c-f4fe-4340-8997-8d7849821d00",
"expires_in": 525,
"scope": "read write"
}
take notice of "access_token" and "token_type" if you want to access any API this is what you have to use. We send the token with API to access data until the token expires then we either refresh it or access for a new one.
for example
$http({
method: "get",
url: "http://192.168.0.4:8085/auth-2-sconnect/api/countries",
withCredentials: true,
headers: {
'Authorization':' [token_type] + [space] + [access_token] '
}
})
.success(function(data) {
alert("success: " + data);
})
.error(function(data, status) {
alert("ERROR: " + data);
});
A simple way to do it:
Just open FireBug in Firefox browser, simulate the login process with the right credentials
Locate the login request in the "NET" tab.
Right-click on it then click on "Copy as cURL"
Paste the copied value in the terminal to see what is expected to be in your cURL request: it looks verbose but you can omit certain
parameters. The required parameters are mentioned in #Rajender Saini answer
up there.
All is done.

How to simulate curl command with Angular

I have this curl command that I would like to simulate with angular:
curl -k -F fieldName=#data.json -u username:Password url
At the moment I went about doing an angular post. However, I run into the problem of authentication. There is no parameter for me to put the user id and password.
Angular code:
$scope.postCall = function () {
$scope.ngResult = "clicked";
var paramsJson = {
"imessageIdT": $scope.messageIdT,
"ilobT": $scope.lobT,
"iregionIdT": $scope.regionIdT,
"iassetClassT": $scope.assetClassT,
"additionalInfoT": $scope.additionalInfoT
};
var config = {
paramsJson: paramsJson
};
$http.post("WEBSITE", paramsJson, config)
.success(function (data, status, headers, config)
{
$scope.ngResult = logResult("POST SUCCESS", data, status, headers, config);
//$scope.ngResult = "Yes";
})
.error(function (data, status, headers, config)
{
$scope.ngResult = logResult("POST ERROR", data, status, headers, config);
//$scope.ngResult = "No";
});
};
Assuming basic authentication, not tested, this might work:
var username = "...", password = "***";
var config = {
headers: {
Authorization: "Basic " + window.btoa(username+":"+password)
},
method: "get", // or "post",
url: "destination.com"
};
$http(config).success(function(){
// on success
}).error(function(){
// on failure
});
The only thing I'm not certain about is window.btoa, if it's an RFC2045-MIME compliant variant of Base64, then you're good.
But my example is an over-simplification. Essentially, you should determine the authentication scheme supported by the server. It could be any one the following specified by IANA:
Basic
Bearer
Digest
HOBA
Negotiate
OAuth
Depending on the required scheme, you should compose the request header accordingly.
This depends on the api you are connecting to. Usually you would log and the server will return you an authentication token on the headers of the response.
1 Basic auth Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==
2 Aoth2 Authorization: Bearer mF_9.B5f-4.1JqM
So you will need to add this header to your request:
$http.post("WEBSITE", paramsJson, angular.extend({}, config, {headers: {
'Authorization': token}}))
If the request is to another domain you should use jsonp.

Oauth 2.0 token based authentication AngularJS (Beginner)

I have gone through multiple documents , Including ng-cordova and oauth-ng but I still can't find any resource which deals with a basic token based authentication in angularjs/Ionic
I am having trouble about how to make this curl call in angularjs
curl -X POST -vu sampleapp:appkey http://sampleurl/oauth/token -H "Accept: application/json" -d "password=pwd&username=sampleuname&grant_type=password&scope=read%20write&client_secret=appkey&client_id=sampleapp"
I am doing this and it's giving me a 401 error. However a curl call works just fine.
$scope.login = function() {
$http({
method: "post",
url: "http://sampleurl/oauth/token",
data: "client_id=" + clientId + "&client_secret=" + clientSecret + "password=pwd&username=sampleuser&grant_type=password" + "&scope=read%20write",
withCredentials: true,
headers: {
'Content-Type': 'application/json; charset=utf-8'
}
})
.success(function(data) {
accessToken = data.access_token;
$location.path("/secure");
})
.error(function(data, status) {
alert("ERROR: " + data);
});
}
I realise that once I get the token , I have to do something similar to
$http.get('http://apiurl/api/v1/users',
{headers: { Authorization: ' Token api_key=xxxxxxxxxxxxxxxxxxxxxxxxxxxx'}})
.then(function(response) {
service.currentUser = response.data.user;
console.log(service.currentUser);
});
But so far I've been unable to figure out a way to make a call to the server and save the access token in my localstorage. All resources on the internet are primarily catered towards 3rd party logins (google,facebook,twitter etc ) or JWT tokens.
I am fairly new at this but I've found out that I need to worry about password grant flow where the user gives his/her credentials to the consumer and the consumer exchanges these for an access and refresh token. Still I don't believe I am making the right call.
UPDATE : As #DanielCottone in the answer below has mentioned , oauth-ng seemed like a good solution but their documentation from what I've seen confuses me as I want to send the username and password to the url too and the sample is not implementing it or has a provision for it from what I can tell?
This is what they have in their documentation :
<oauth
site="http://oauth-ng-server.herokuapp.com"
client-id="d6d2b510d18471d2e22aa202216e86c42beac80f9a6ac2da505dcb79c7b2fd99"
redirect-uri="http://localhost:9000"
profile-uri="http://oauth-ng-server.herokuapp.com/api/v1/me"
scope="public">
</oauth>
Again , this is a first time I'm trying integration of any kind and it makes sense for me to think that the call will have credentials sent with it? How do I send it then ?
The best way to solve this is by storing the token in localStorage after authentication, and then using an interceptor to inject the token into your request headers:
$http authentication promise (you need to inject $localStorage)
.success(function(data) {
$localStorage.accessToken = data.access_token;
$location.path("/secure");
})
Authentication interceptor
.factory('AuthInterceptor', function ($q, $localStorage, $rootScope) {
return {
request: function (config) {
if ($localStorage.access_token) {
config.headers['Authorization'] = 'Token api_key=' + $localStorage.token;
}
return config;
},
responseError: function (response) {
if (response.status === 401 || response.status === 403) {
delete $localStorage.access_token;
// Do some kind of redirect to login page here...
}
return $q.reject(response);
}
};
});
To logout, you would just delete the token from localStorage, and all further requests would be redirected to the login page if you get a 401 or 403 from the API.

Ionic Framework Login with php RestAPI

I am building an app which needs to be talk to a spring backend to log in users. I did a cURL post of
curl -X POST -vu sampleapp:appkey http://sampleurl/oauth/token -H "Accept: application/json" -d "password=pwd&username=sampleuname&grant_type=password&scope=read%20write&client_secret=appkey&client_id=sampleapp"
I get the desired response as :
{
"access_token":"xxx",
"token_type":"bearer",
"refresh_token":"xxx",
"expires_in":43199,
"scope":"read write"
}
In the app end, I have a button which calls the function below . I am getting CORS error (401 Unauthorized) as of now but I still can't help feel that I'm not calling it in a correct way.Here's what I have
$scope.login = function() {
$http({
method: "post",
url: "http://sampleurl/oauth/token",
data: "client_id=" + clientId + "&client_secret=" + clientSecret + "password=pwd&username=sampleuser&grant_type=password" + "&scope=read%20write",
withCredentials: true,
headers: {
'Content-Type': 'application/json; charset=utf-8'
}
})
.success(function(data) {
accessToken = data.access_token;
$location.path("/secure");
})
.error(function(data, status) {
alert("ERROR: " + data);
});
}
I am just not sure if the way I'm implementing it is correct. I have looked into all possible online resources but 99% of them are about integrating with Social Network accounts. I want something which will let me log in and access profile information exposed through
/user/{username}
I have looked into the option of using ng-Resource but I still don't know how to make the authentication call. For a call to twitter/facebook api , the format followed is not giving me the desired result.
Any help or link to resources will be greatly appreciated.

Resources