I am working on Spring Boot and Spring Rest application. The Security Testing have reported the issue
"The web application or services inform web client of the allowed domain using the HTTP response header Access-Control-Allow-Origin. The header can contain a '*' to indicate that all domain are allowed."
Remediation -
Use the Access-Control-Allow-Origin header only on chosen URLs that need to be accessed cross-domain. Don't use the header for the whole domain.
While making the HTTP request, they've used origin: null, then Access-Control-Allow-Origin: *
How can I implement this?
use this in your project, I think it will solve your problem,
import org.springframework.web.filter.OncePerRequestFilter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class Filter extends OncePerRequestFilter {
#Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
response.setHeader("Access-Control-Allow-Origin", "*");
response.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
response.setHeader("Access-Control-Max-Age", "3600");
response.setHeader("Access-Control-Allow-Headers", "authorization, content-type, xsrf-token, token");
response.addHeader("Access-Control-Expose-Headers", "xsrf-token");
if ("OPTIONS".equals(request.getMethod())) {
response.setStatus(HttpServletResponse.SC_OK);
} else {
filterChain.doFilter(request, response);
}
}
}
Related
So, like many before me, I'm also facing the CORS error with AWS API gateway+Lambda(python) for a POST request.
Let me explain the Homeworks I did.
Followed the links and got a basic idea of how CORS works.
Tried enabling lambda proxy integration and tried without it as well.
During the manual configuration attempt I added the "Access-Control-Allow-Origin":'*' manually in API gateway method configurations.
At all times my lambda function is set to return the headers like below:
'headers': {
'Access-Control-Allow-Headers': 'Content-Type',
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Methods': 'OPTIONS,POST,GET'
}
Postman is working fine as it worked for most of the people who had issues.
When I check the network traffic in chrome, I get the 'Access-Control-Allow-Origin': '*' as part of the header for OPTIONS. But when POST request has none of these headers I have added in the lambda.
The destination page is hosted in my local and AWS Amplify and both has the same issue.
Few images for reference.
Looking forward to all of your inputs.
Edit:
Adding my lambda code as requested:
import json
import urllib.parse
import boto3
import configparser
import os
import datetime
import json
print('Loading function')
# some more code here...
def lambda_handler(event, context):
logfilename = log(json.dumps(event, indent=2), "Debug")
response = {
'headers': {
'Access-Control-Allow-Headers': 'Content-Type',
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Methods': 'OPTIONS,POST,GET'
},
"statusCode": 200,
"body": "{\"result\": \"Success.\"}"
}
return response
You need to add "Secure; SameSite=None" to the cookie you send with the lambda response and add withCredentials: true to your axios request.
Important! The cookie will not be accessible with JS inside you app (as it is httpOnly one). But it will be added to external HTTP requests (execute with axios withCredentials: true)
I am working with the CF API RESTful services. Trying to get an access token from cloud foundry's UAA API using https://login..../oauth/token web method.
I have verified that headers & body content is correct, but calling the api always returns a 400 error code with message missing grant type.
I have implemented this call in Objective-C, Swift & now Python. All tests return the same result. Here is my code example in Python:
import json
import requests
import urllib
params = {"grant_type": "password",
"passcode": "xxx"
}
url = "https://login.system.aws-usw02-pr.ice.predix.io/oauth/token"
headers = {"Authorization": "Basic Y2Y6", "Content-Type": "application/json", "Accept": "application/x-www-form-urlencoded"}
encodeParams = urllib.parse.urlencode(params)
response = requests.post(url, headers=headers, data=encodeParams)
rjson = response.json()
print(rjson)
Each time I run this, I get the response
error invalid request, Missing grant type
Any help would be greatly appreciated.
Your code mostly worked for me, although I used a different UAA server.
I had to make only one change. You had the Accept and Content-Type headers flipped around. Accept should be application/json because that's the format you want back, and Content-Type should be application/x-www-form-urlencoded because that's the format you are sending.
See the API Docs for reference.
import json
import requests
import urllib
import getpass
UAA_SERVER = "https://login.run.pivotal.io"
print("go to {}/passcode".format(UAA_SERVER))
params = {
"grant_type": "password",
"passcode": getpass.getpass(),
}
url = "https://login.run.pivotal.io/oauth/token"
headers = {
"Authorization": "Basic Y2Y6",
"Content-Type": "application/x-www-form-urlencoded",
"Accept": "application/json"
}
encodeParams = urllib.parse.urlencode(params)
response = requests.post(url, headers=headers, data=encodeParams)
rjson = response.json()
print(json.dumps(rjson, indent=4, sort_keys=True))
I made a couple other minor changes, but they should affect the functionality.
Use getpass.getpass() to load the passcode.
Set the target server as a variable.
Pretty print the JSON response.
The only other thing to note, is that the OAuth2 client you use must be allowed to use the password grant type. It looks like you're using the same client that the cf cli uses, so if your UAA server is part of a standard Cloud Foundry install that is likely to be true, but if it still doesn't work for you then you may need to talk with an administrator and make sure the client is set up to allow this.
I am able see items in browser If I use it in browser. I use same url within service below, and there is no response, if I change url with some global api url for exp: "https://api.spotify.com/v1/search?type=artist&q=" it works as I expected. so actually service works also.
It means my problem about sharepoint list api, it requires some specific parameters, but cant figure it out what I did in browser but did not in http request in that service.
api.service:
import {Http} from '#angular/http';
import {Observable} from 'rxjs/Observable';
import 'rxjs/add/operator/map';
import {Injectable} from '#angular/core';
#Injectable()
export class dService {
constructor(private http_: Http){}
getAnnouncements(urllapi){
return this.http_.get(urllapi).map(res=>res.json());
}
}
-
//this.someService.getAnnouncements("https://api.spotify.com/v1/search?type=artist&q=") it works as I expected
this.someService.getAnnouncements("http://milespoint1:33333/_api/web/lists/getByTitle('Announcement5Jan')/items").subscribe((res) => {
debugger
this.tweetsdata = res.json().data.statuses;
this.isLoading=false;
console.log("spotify service data:"+res)});
browser:
If you don't request for strictly JSON data SharePoint REST API will give you XML data (same data as your browser) thus making your
this.tweetsdata = res.json()
line to fail. Try changing your service constructor and method to
import {Http, Response, Headers} from '#angular/http';
import {Observable} from 'rxjs/Observable';
import 'rxjs/add/operator/map';
import {Injectable} from '#angular/core';
#Injectable()
export class dService {
private headers: Headers;
constructor(private http_: Http){
this.headers = new Headers();
this.headers.append('Content-Type', 'application/json');
this.headers.append('Accept', 'application/json;odata=verbose');
}
getAnnouncements(urllapi){
return this.http_.get(urllapi, {headers: this.headers}).map(res=>res.json());
}
}
Let me know if that helps.
I am trying to fetch some files from internet. I want to update my schedule service if the last modified time update. With HTTPBuilder I am unable to find the server response with last-modified parameter. Is there any way to get this parameter?
As in the docs Last-Modified is a header and should be searched among other headers. What's important is that it's server that decides if Last-Modified header will be included in the response. Hence, if the server you connect to doesn't return the header in the response it's impossible to get the value.
Headers can be obtained via response object, see below:
#Grab(group='org.codehaus.groovy.modules.http-builder', module='http-builder', version='0.7.1')
import groovyx.net.http.HTTPBuilder
import static groovyx.net.http.Method.GET
import static groovyx.net.http.ContentType.TEXT
def http = new HTTPBuilder( 'http://www.google.com/search' )
http.request(GET,TEXT) { req ->
response.success = { res ->
res.headers.each { h ->
println h
}
}
}
im doing an api for pin payment in pin.net.au and i encounter some errors like what you see in the bottom
`#Grab(group='org.codehaus.groovy.modules.http-builder', module='http-builder'`,` version='0.5.0-RC2' )
import groovyx.net.http.*
import groovyx.net.http.HttpResponseDecorator
import groovyx.net.http.RESTClient
import static groovyx.net.http.ContentType.*
import groovyx.net.http.HttpResponseException
import groovy.swing.SwingBuilder
import javax.swing.JFrame
import wslite.http.auth.*
class Customers {
Customers(){
def rst = new RESTClient( 'https://test-api.pin.net.au/1/')
rst.auth.basic 'mySecretKey',''
def res = rst.post( path: 'customers'){
type ContentType.XML
xml {
cards{
email('pk_qTj9Umqmlf3o7lfa6F9nWw')
card[expiry_month]('12')
card[expiry_year]('2015')
card[cvc]('123')
card[name]('patrick pl')
card[address_line1]('23 frfds')
card[address_city]('Angeles')
card[address_postcode]('2009')
card[address_state]('ph')
card[address_country]('Philippines')
}
}
}
}
public static void main(String []args){
new Customers()
}
}
when i run the code the error was
May 12, 2014 1:07:35 PM org.apache.http.impl.client.DefaultRequestDirector handleResponse
WARNING: Authentication error: Unable to respond to any of these challenges: {}
Caught: groovyx.net.http.HttpResponseException: Authorization Required
groovyx.net.http.HttpResponseException: Authorization Required
at groovyx.net.http.RESTClient.defaultFailureHandler(RESTClient.java:240)
at groovyx.net.http.HTTPBuilder.doRequest(HTTPBuilder.java:475)
at groovyx.net.http.HTTPBuilder.post(HTTPBuilder.java:335)
at groovyx.net.http.HTTPBuilder$post.call(Unknown Source)
at PinPayment.Customers.<init>(Customers.groovy:16)
at PinPayment.Customers.main(Customers.groovy:39)
how could i make the authentication work for the code to be runable??
here is the link for the docs pin.net.au
Document indicates it requires basic HTTP authn.
Calls to the Pin Payments API must be authenticated using HTTP basic
authentication, with your API key as the username, and a blank string
as the password.
Therefore:
def rst = new RESTClient( 'https://test-api.pin.net.au/1/' )
rst.auth.basic 'secretAPIKeyHereAsString', ''
i found the right code for that particular api here def http = new RESTClient('https://test-api.pin.net.au/1/') http.headers['Authorization'] = 'Basic '+"tWqZl0MHsg5nUQdB6czrDQ:".getBytes('iso-8859-1').encodeBase64()