We have a proxy running that serves HTTPS pages to the internet. Therefore it redirects requests into our DMZ where the pages are served as HTTP pages.
We got WireCloud set up to run at a subdomain: wirecloud.example.com. Horizon runs at horizon.example.com.
In Horizon the Callback URL is set to: http://wirecloud.example.com/complete/fiware/ and in the settings.py of Wirecloud the FIWARE_IDM_SERVER = 'http://horizon.example.com' is set.
Now, when wirecloud.example.com/login gets called, it is redirected to https by our proxy and then redirected to horizon by wireclound what then gets redirected by our proxy to https://horizon.example.com/oauth2/authorize/?state=STATE_KEY&redirect_uri=http://wirecloud.example.com/complete/fiware/&response_type=code&client_id=CLIENT_ID. If the user is not logged in and now does so the redirect_uri gets transformed to this: http%253A%252F%252Fwirecloud.example.com%252Fcomplete%252Ffiware%252F what leads to this error: {"state": "STATE_KEY", "error": "invalid_redirect_uri"} (HTTP 400). If the user is already logged in and tries to authorize the app (WireCloud) a 405 error gets thrown:
Environment:
Request Method: GET
Request URL: http://wirecloud.example.com/complete/fiware/?state=STATE_KEY&code=CODE
Django Version: 1.9.6
Python Version: 2.7.9
Installed Applications:
('django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'django.contrib.admin',
'wirecloud.commons',
'compressor',
'wirecloud.catalogue',
'wirecloud.platform',
'wirecloud.oauth2provider',
'wirecloud.fiware',
'social.apps.django_app.default')
Installed Middleware:
('wirecloud.commons.middleware.URLMiddleware',)
Traceback:
File "/opt/wc/venv/lib/python2.7/site-packages/django/core/handlers/base.py" in get_response
149. response = self.process_exception_by_middleware(e, request)
File "/opt/wc/venv/lib/python2.7/site-packages/django/core/handlers/base.py" in get_response
147. response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/opt/wc/venv/lib/python2.7/site-packages/django/views/decorators/cache.py" in _wrapped_view_func
57. response = view_func(request, *args, **kwargs)
File "/opt/wc/venv/lib/python2.7/site-packages/django/views/decorators/csrf.py" in wrapped_view
58. return view_func(*args, **kwargs)
File "/opt/wc/venv/lib/python2.7/site-packages/social/apps/django_app/utils.py" in wrapper
51. return func(request, backend, *args, **kwargs)
File "/opt/wc/venv/lib/python2.7/site-packages/social/apps/django_app/views.py" in complete
28. redirect_name=REDIRECT_FIELD_NAME, *args, **kwargs)
File "/opt/wc/venv/lib/python2.7/site-packages/social/actions.py" in do_complete
43. user = backend.complete(user=user, *args, **kwargs)
File "/opt/wc/venv/lib/python2.7/site-packages/social/backends/base.py" in complete
41. return self.auth_complete(*args, **kwargs)
File "/opt/wc/venv/lib/python2.7/site-packages/social/utils.py" in wrapper
229. return func(*args, **kwargs)
File "/opt/wc/venv/lib/python2.7/site-packages/social/backends/oauth.py" in auth_complete
383. method=self.ACCESS_TOKEN_METHOD
File "/opt/wc/venv/lib/python2.7/site-packages/social/backends/oauth.py" in request_access_token
361. return self.get_json(*args, **kwargs)
File "/opt/wc/venv/lib/python2.7/site-packages/social/backends/base.py" in get_json
229. return self.request(url, *args, **kwargs).json()
File "/opt/wc/venv/lib/python2.7/site-packages/social/backends/base.py" in request
225. response.raise_for_status()
File "/opt/wc/venv/lib/python2.7/site-packages/requests/models.py" in raise_for_status
844. raise HTTPError(http_error_msg, response=self)
Exception Type: HTTPError at /complete/fiware/
Exception Value: 405 Client Error: METHOD NOT ALLOWED for url: https://horizon.example.com/oauth2/token
So how do we need to configure WireCloud and/or Horizon and/or our proxy to get this to work?
Edit your settings.py file and add the following lines for forcing WireCloud to use https for the internal urls:
FORCE_PROTO = 'https'
SOCIAL_AUTH_REDIRECT_IS_HTTPS = True
This should make WireCloud to use https://wirecloud.example.com/complete/fiware/ as the redirect_uri. See the FORCE_PROTO for more details.
Regarding, this exception:
Exception Type: HTTPError at /complete/fiware/
Exception Value: 405 Client Error: METHOD NOT ALLOWED for url: https://horizon.example.com/oauth2/token
I need more info for being 100% sure, but seems a problem regarding network visibility. I think that the WireCloud machine is requesting the https://horizon.example.com/oauth2/token URL, but this request is not passing through your proxy/frontend server. You can confirm this case, if you have a valid token, by executing the following line from the WireCloud machine and from an external machine:
curl -v https://horizon.example.com/oauth2/token?access_token=*****
Related
I encounter a problem when I try to call the Teamcity REST service through a TFS extension.
I configured TeamCity as well:
rest.cors.origins = "http://my.tfsserver"
rest.cors.optionsRequest.allowUnauthorized = true
In the TFS extension, I call the following url:
http: //my.teamcity.server:80/app/rest/latest/projects using "XMLHttpRequest"
const pair :string=this.settings.username+":"+this.settings.password;
const encodedCreds:string = btoa(pair);
const basicAuthValue:string = "Basic "+ encodedCreds;
const apiurl:string="/app/rest/latest/projects";
const completeUrl:string = this.settings.urlTeamCity+apiurl;
const xhr = new XMLHttpRequest();
xhr.open("GET",completeUrl,true);
xhr.setRequestHeader('Authorization', basicAuthValue);
xhr.setRequestHeader("Access-Control-Allow-Origin" ,"http://my.tfsserver");
xhr.onload=function(){
console.log(xhr.responseText);
}
xhr.onerror=function(){
console.log(xhr.response);
}
xhr.send();
I'm getting the following error in the console:
Failed to load http://my.teamcity.server:80/app/rest/latest/projects:
Response for preflight is invalid (redirect)
In the TeamCity rest log, i have the following two lines:
[2018-10-01 14:12:49,891] DEBUG [p-nio-80-exec-9] -
er.rest.APIController/rest-api - Got CORS request from origin 'null',
but this origin is not allowed. Add the origin to 'rest.cors.origins'
internal property (comma-separated) to trust the applications hosted
on the domain. Current allowed origins are: Enabled CORS Origins:
[http://my.tfsserver]
[2018-10-01 14:12:49,892] DEBUG [p-nio-80-exec-9] -
er.rest.APIController/rest-api - REST API request processing finished
in 1ms, status code: 302, request: OPTIONS
'/app/rest/latest/projects', from client 10.69.152.71:59256, no auth
Based on the last line, i modify my code to:
...
xhr.open("GET",completeUrl,true,this.settings.username,this.settings.password)
xhr.withCredentials=true;
...
but, i'm still getting the same error in both chrome console and team city rest log.
in the chrome console, on the network tab, i can see that "origin" header is null but i don't understand why?
Thanks by adavance for any help :)
I have this very simple Ruby code which makes Ruby POST request.
For some reason it creates 2 requests - one authentication error and one successful request:
def execute
request = HTTPClient.new()
request.ssl_config.verify_mode = OpenSSL::SSL::VERIFY_NONE
request.set_auth('https://test.net/api', 'user', 'pass')
request_body = File.read("requests/xml/req.xml")
response = request.post('https://test.net/api', request_body, {'Content-Type' => 'application/xml', 'cache-control' => 'no-cache'}).body
puts 'called'
end
I suppose that some configuration if missing for HTTPClient?
Can you advise how I can fix this?
This is an expected behavior. The client won't send the credentials unless they are required. When the client gets a 401 status code then it sends the request again but now with the credentials.
You can force some clients to send the credentials on the first request.
Ruby's HTTPClient has a force_basic_auth that does that.
I am using Faye websocket implementation. When a websocket is detected I want to make sure the user sent a given header before I open the connection, or else I want to return an error.
I tried returning error 401 using [] but I keep oberving that the code continues execution and the websocket is created anyway. I managed to prevent it by adding return after it, but I am not sure this is the right way. On the client side I am implementing it in python using ws4py and when I return I get an exception raised indicating it received a 302 code, not the 401 I was expecting to send.
My ruby code (without the websocket events code) follows:
App = lambda do |env|
if Faye::WebSocket.websocket?(env)
unless env['HTTP_MY_HEADER']
[401, {'Content-Type' => 'application/json'}, '{"message": "I was expecting a header here"}']
#return (??)
end
ws = Faye::WebSocket.new(env)
# Rest of websocket call handling
else
# Normal HTTP request
[200, {'Content-Type' => 'text/plain'}, ['Hello']]
end
end
I have an web app which I bundled using webpack, I placed my entire react/redux app in the public file which will be served by nodejs(express-generator). My app works when I run in localhost/ local env. However when I deploy to heroku. I cannot make calls.
The below is the error message:
bundle.js:19 GET https://glacial-cove-64389.herokuapp.com/users/ 401 (Unauthorized)
Object {err: Error: Request failed with status code 401 at e.exports (https://glacial-cove-64389.herokuapp.co…}
err
:
Error: Request failed with status code 401 at e.exports (https://glacial-cove-64389.herokuapp.com/bundle.js:19:10382) at e.exports (https://glacial-cove-64389.herokuapp.com/bundle.js:26:6821) at XMLHttpRequest._.(anonymous function) (https://glacial-cove-64389.herokuapp.com/bundle.js:19:9464)
__proto__
:
Object
initially I thought it could be my my ROOT_URL so I changed it the below is an example of my actions file.
const ROOT_URL = "//glacial-cove-64389.herokuapp.com"
const axiosOption = {headers: { authorization : localStorage.getItem('token')}}
/*Sign in user*/
export function signinUser({ email, password }){
return function(dispatch){
axios.post(`${ROOT_URL}/users/signin`, { email, password })
.then(function(res){
dispatch({ type: AUTH_USER })
localStorage.setItem('token', res.data.token);
browserHistory.push('/users');
})
.catch(function(err){
dispatch(authError('Invalid email or password'))
console.log({err});
})
}
}
So what happens is that the react recognize the login and push user to the correct route. but it return the above error msg status code 401 once it hits the main pages.
The main problem I have is when I try to perform CRUD which doesn't work
Here is my repo: https://github.com/boyboi86/API_basic_random
I found out the hard way..
If you intend to put everything within your public file when scaffold with express-generator. Putting CORS within your Nodejs is insufficient because now your axios (react) that makes the call is also subjected to CORS, And you will have to config within your axios with the following:
axios.defaults.headers.post['Access-Control-Allow-Methods'] = 'PATCH, DELETE, POST, GET, OPTIONS';
This is to ensure all calls made will be allowed. I realised this when I look at the response headers.
While using the Wistia API, I've encountered this strange phenomena: 200 in browser, 404 from HTTParty.
Currently, I have a video module with an embed class as so:
module Video
class Embed
include ActiveModel::Model
include HTTParty
base_uri 'https://fast.wistia.net/oembed'
format :json
default_params api_password: ENV['WISTIA_PASSWORD']
class << self
def find(hashed_id)
get("", query: { url: url_query("#{hashed_id}") })
end
private
def url_query(hashed_id)
"http%3A%2F%2Fhome%2Ewistia%2Ecom%2Fmedias%2F#{hashed_id}"
end
end
end
end
When performing a Video::Embed.find(#video.hashed_id) the code that is output appears as so in the log:
HTTP GET (59.97ms) https://fast.wistia.net:443/oembed?api_password=not_getting_my_password&url=http%3A%2F%2Fhome%2Ewistia%2Ecom%2Fmedias%2Fth3-3Xamp13
Response status Net::HTTPNotFound (404)
Response body
But, if I paste in my url, I can see the JSON load inside of the browser (200).
The password is correct (tested), the hashed_id is correct (tested), and the URL was tested by pasting in the url into the browser.
I have a feeling its a cross-origin issue, but even then I'm not sure how to solve that one.
Update: Performing a curl returns the JSON just like the browser.