Use Google Access Token from another origin API - google-app-engine

I need to access to a ASP.net Core API store on Google App Engine from a web page using Google API JS .
For Example :
I've got this script that use Localstorage to store the generated access token
function onSignIn(googleUser) {
var profile = googleUser.getBasicProfile();
var token = googleUser.getAuthResponse().id_token;
LocalStorage.setItem("accessToken", token);
DisplayValues2();
}
function DisplayValues2() {
$.ajax({
url: 'http://localhost:49389/api/values',
method: 'GET',
headers: {
'content-type': 'application/JSON',
'Authorization': 'Bearer ' + localStorage.getItem("accessToken")
},
success: function (data) {
$('#divSuccess').text("");
$('#divSuccess').text(data);
$('#divSuccess').show('fade');
},
error: function (jQXHR) {
if (jQXHR.status == "401") {
$('#errorModal').modal('show');
}
else {
$('#divErrorText').text(jQXHR.responseText);
$('#divError').show('fade');
}
}
});
};
*here the LocalHost:49389 it's just the project that will be push on App Engine
From my http://Localhost:59638/login.html (with the script above) I want to access to the http://localhost:49389/api/values API
My Asp.net Core project is on VS2017 with ASP.Net Core On Google Cloud Platform Web API template.
ValuesController :
[Route("api/[controller]")]
[ApiController]
public class ValuesController : Controller
{
// GET api/values
[HttpGet]
[Authorize]
public IEnumerable<string> Get()
{
return new string[] { "value1", "value2", "value3", "value4", "value5" };
}
}
The only thing that change after created the project is the [Authorize] attribute and I receive a :
500 internal server error
And I would like to know,
what should I implement to authenticate the Google token sent in the HTTP header with this API?
Thx

The first thing you will need to do is to ensure that you are telling the authorize to accept a bearer token
[Authorize(AuthenticationSchemes = "Bearer")]
Second is your going to have to make sure that you have the api setup to validate authentication against googles OAuth server.

Related

Rest Service not working when deployed on AWS

This is my Rest Service.
#RestController
public class ProjectController {
#RequestMapping(method = RequestMethod.GET, value = "/getProjects")
public ArrayList<Project> getProjects() {
ArrayList<Project> projectList = new ArrayList<Project>();
ProjectDao obj = new ProjectDao();
projectList = obj.getProjects();
return projectList;
}
}
And this is my Angular script to invoke this service.
$http({
method: "GET",
url: "/getProjects"
})
.then(
function success(response) {
...
},
function error {
alert("Error");
}
);
These are working fine when I run the application on my localhost. But, it fails when I deploy my spring-boot application on AWS and run it on server. Server returns HTTP Status 404 - The requested resource is not available instead of JSON data when I enter the URL of the service in browser. What's the problem here?
Mkyong solved it.
Here is the solution.
add #CrossOrigin annotation with #RestController

Auth0 NodeJS Authentification Refused using npm request

I'm facing a problem, I tried to connect to Auth0 API to enable a strong identification on my WebApp.
For context :
Front-End : I'm using an angularJS front, and there I implemented the Lock Library to manage the Auth0 popup by following this webapp-specific tutorial.
Back-End : NodeJS & Express server, in order to verify the user's authentification, I use the npm lib "request" to call the Auth0 API.
If i understand well, a click on the auth0 widget sends a request to the specified endpoint URL, and it's received by the back-end:
app.get('/auth0CallbackURL', function (req, res) {
console.log(req.query.code);
var auth0code = req.query.code;
var client_secret = PROCESS.ENV.SERCRETID;
var domain = PROCESS.ENV.DOMAIN;
var client_id = PROCESS.ENV.CLIENTID;
var redirectUrl = PROCESS.ENV.REDIRECTURL;
var request = require('request'); // request-promise
var requestParams = {
url: 'https://mycompanydomain.auth0.com/oauth/token?client_id='+client_id+'&redirect_uri='+redirectUrl+'&client_secret='+client_secret+'&code='+auth0code+'&grant_type=authorization_code',
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
}
}
And then I call request() to get back the access_token and verify the authentification.
request(requestParams, function(err, data) {
if (err) {
console.log('Err:', err);
} else {
console.log('response body: ', data.body)
}
But the only result I get is :
{
"error": "access_denied"
"error_description": "Unauthorized"
}
At the begining i thougt it was my Auth0 configuration that's didn't allow my authentification, but it seems that there are OK.
Thanks in advance for your replies.
As per the page you linked, you need to pass the following information:
client_id=YOUR_CLIENT_ID
&redirect_uri=https://YOUR_APP/callback
&client_secret=YOUR_CLIENT_SECRET
&code=AUTHORIZATION_CODE
&grant_type=authorization_code
in the request body and with a content type of application/x-www-form-urlencoded.
You're setting the content type correctly, but then are passing the data in the URL query component and instead you need to pass it the POST request body.
Using request package you should do the following:
var requestParams = {
url: 'https://mycompanydomain.auth0.com/oauth/token',
method: 'POST',
body: 'client_id=' + client_id +
'&redirect_uri=' + redirectUrl +
'&client_secret=' + client_secret +
'&code=' + auth0code +
'&grant_type=authorization_code',
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
}
}

Basic Authentication of spring with Restangular

I am using Restangular with Spring's oauth security and in the client side i am using Restangular for login request.
Code in OAuth2ServerConfiguration:
#Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients
.inMemory()
.withClient("clientapp")
.authorizedGrantTypes("password", "refresh_token")
.authorities("USER")
.scopes("read", "write")
.secret("abc");
}
Login with postman needs these configurations:
1-Set Authorization as "Basic Auth".
2-Set username,password as {"username":"clientapp","password":"abc"}//credentials to access server side
3-In request body through "x-www-form-urlencoded" three parameters are sent.
{"username":"abc#gmail.com","password":"abc123","grant_type":"password"}//credentials to login which are checked from database.
This will do a successful login.but i cannot understand how to use these configurations in Angular JS Restangular call.
currently m trying with this.
In Config:
RestangularProvider.withConfig(function (RestangularConfigurer) {
return RestangularConfigurer.setDefaultHeaders({ "Authorization": "Basic Y2xpZW50YXBwOkxNUw==",
"username":"clientapp",
"password":"abc",
"Content-type": "application/x-www-form-urlencoded; charset=utf-8"
});
In Controller:
Restangualar.all("oauth/login").post({username;$scope.user.username,
password:"$scope.user.password","grant_type":"password"}).then(function(){
console.log(res);
});
But I am getting this error:
error:"unauthorized",error_description:"Full authentication is required to access this resource"
in browser.
Note:This resource is not secured.
Any Solution???
Update: I forgot to added a main information that my frontend with angular is running independently on localhost(through xampp) while spring login backend is on localhost:8080..
Error in network tab:
2-
public void configure(HttpSecurity http) throws Exception {
// #formatter:off
http
.authorizeRequests()
.anyRequest().permitAll()
//.antMatchers("/users").permitAll()
.antMatchers(HttpMethod.OPTIONS, "/oauth/token").permitAll()
.and().csrf().disable();
}
3-
endpoints
.tokenStore(this.tokenStore)
.authenticationManager(this.authenticationManager)
.userDetailsService(userDetailsService)
.addInterceptor(new HandlerInterceptorAdapter() {
public boolean preHandle(HttpServletRequest hsr, HttpServletResponse rs, Object o,FilterChain chain) throws Exception {
rs.setHeader("Access-Control-Allow-Origin", "*");
rs.setHeader("Access-Control-Allow-Methods", "GET,OPTIONS,POST");
// rs.setHeader("Access-Control-Max-Age", "7200");
rs.setHeader("Access-Control-Allow-Headers", "Origin, X- Requested-With, Content-Type, Accept, Authorization");
HttpServletRequest httpServletRequest = (HttpServletRequest) hsr;
if (httpServletRequest.getMethod().equalsIgnoreCase("OPTIONS")) {
chain.doFilter(hsr, rs);
} else {
// In case of HTTP OPTIONS method, just return the response
return true;
}
return false;
}
});
You can use Restangular custom post. See documentation.
Example:
Restangular.service("/oauth/login").one().customPOST(
{},
'',
{
// Params...
grant_type: 'password',
client_id: 'clientapp',
client_secret: 'abc',
username: 'abc#gmail.com',
password: 'abc123',
scope: 'read, write'
},
{
// headers...
}).then(
function (response) {
// Manage successfull response
},
function () {
// Manage error response
}
);
Hope it helps
UPDATED:
It seems to be a CORS problem, lots of answers already for it, but in your case using XAMPP you will need to configure your apache server:
https://enable-cors.org/server_apache.html.
PREVIOUS ANSWER BEFORE UPDATE:
The advantage of using restangular is the ability to manage resources in a more semantic way and the ability to get nested resources. All these advantages don't really apply for a call just to retrieve a token from an oauth2 provider.
I would recommend to forget about using restangular for this specific call (you still can use it for everything else in your application) and convert this call to a simple $http.post.
$http.post('oauth/login',
{ username;$scope.user.username,
password:"$scope.user.password",
"grant_type":"password"
},
{
headers: { "Authorization": "Basic Y2xpZW50YXBwOkxNUw==",
"username":"clientapp",
"password":"abc",
"Content-type": "application/x-www-form-urlencoded; charset=utf-8"
}
})
.then(function(response) {
Restangular.setDefaultHeaders({
"Authorization": "Bearer " + response.token
});
});
So, you just use $http.post, and on its response set the default headers in angular to use the retrieved token.
Cheers,

ASP.NET API Controller POST/Redirect/Get

I would like to use the P/R/G design with this API, using AngularJS on the client side. Here is my API method:
[HttpPost]
public HttpResponseMessage UpdateRaw(HttpRequestMessage request)
{
//do stuff...
var res = request.CreateResponse(HttpStatusCode.Redirect);
var authority = request.RequestUri.Authority;
var uri = string.Concat(authority, "/api/DataApi/GetRaw");
res.Headers.Location = new Uri(uri);
res.Headers.Add("Access-Control-Allow-Origin", "*");
return res;
}
I have another method in this controller (DataApiController) which is called GetRaw(). Basically I want the client to issue a POST, call this method, then get redirected to the GET method. Here is my JS code:
//get the data and build the js rep
$http({
method: 'POST',
url: '/api/DataApi/UpdateRaw',
headers: {
'Content-Type': undefined
},
data: {
test: "test"
}
}).then(function (result) {
console.log("RAW--------------");
console.log(result.data);
// do stuff...
}, function () { console.log("DIDN'T WORK"); });
When I issue the POST, however, my browser console says "The request was redirected to a URL ('localhost:25498/api/DataApi/GetRaw') which has a disallowed scheme for cross-origin requests." I am aware of this answer, but that had the same result.
I found another website somewhere which suggested adding the line
res.Headers.Add("Access-Control-Allow-Origin", "*");
but that does not seem to work either.
I am new to ASP.NET and Web Dev in general, so any ideas would be appreciated. Thanks.

Angular $http post with custom headers

I am new to angular and am from .net framework. I need to post a angular request to .net service, where it expects two custom headers from the client.
angular post command:
var request = $http(
{
url: "http://localhost:53585/api/myService/Validate",
method: "POST",
data: JSON.stringify(payload),
headers: { 'first_token': sessionService.first_token, 'second_token': sessionService.second_token }
});
But in the service side, I can see only first_token in the request header and not the second token. What I am missing here?
Issue is with my service. I figured out and restarted the IIS and then service was able to read both the headers token
I found this method in a forum, it works.
return this.http.post<any>('https://yourendpoint', { username, password }, { headers: new HttpHeaders().set('Authorizaion', 'your token')})
.pipe(map(user => {
// login successful if there's a jwt token in the response
if (user && user.token) {
// sto`enter code here`re user details and jwt token in local storage to keep user logged in between page refreshes
localStorage.setItem('currentUser', JSON.stringify(user));
}
console.log(user);
return user;

Resources