Google App Engine custom domain mapped to secure site - google-app-engine

I have mapped my custom domain to GAE custom domain mappings. My domain resides at godaddy.com.
The mapping works and it always points to non-secure site, where as a secure site does exist.
I want on typing non secure site it should auto direct to secure site. I tried to use forward mechanism on loads, but somehow it gets in a loop from secure to non-secure.

You can try the following 3 approaches :
To send HTTPS requests with your custom domain, you can use the
managed SSL certificates, like mentioned here which says
“By default, HTTPS connections on your custom domain will be enabled
automatically using managed SSL certificates”.
To force HTTPS for your app, you can specify the secure: always
element for each handler in your app.yaml. Using secure: always
redirects all HTTP traffic to an HTTPS URL.
For example:
handlers:
- url: /.*
script: auto
secure: always
redirect_http_response_code: 301
To instruct the browser to prefer https over http for a given page or
entire domain, set the Strict-Transport-Security header in your
responses. Add the header to your app's static file and directory
handlers.
For example:
Strict-Transport-Security: max-age=31536000; includeSubDomains

Related

Google app engine prevent OPTIONS request between two services

I've created a GAE project and I deployed two services:
default (https://myservice.appspot.com) for the front-end app
backend (https://backend-dot-myservice.appspot.com) for the backend (Node.js)
I've also added a custom domain so that the default service is reachable also at https://myservice.com.
The problem I have is that each AJAX requests performed by the browser is preceded by an OPTIONS request (to handle the CORS).
What's the best solution to avoid this OPTIONS request? It should be fixed if both front-end/backen-end are on the same host, but how can I do it on Google App Engine?
Thank you!
I solved adding a dispatch.yaml file on the default service
dispatch:
- url: "*/api/*"
service: backend
where backend is my backend service.
And I changed my backend in order to listen on addresses like /api/something.
So now the browser has origin https://myservice.com and the url of ajax requests to the beckend are like https://myservice.com/api/something.
Since now client and server have the same origin, the CORS settings is not needed anymore, and the OPTIONS request is not performed by the browser.
I don't know if it's the best solution, but for me it worked.
As it was mentioned in this Stackoverflow post:
OPTIONS requests are pre-flight requests in Cross-origin resource sharing (CORS).
This pre-flight request is made by some browsers as a safety measure to ensure that the request being done is trusted by the server. Meaning the server understands that the method, origin and headers being sent on the request are safe to act upon.
Your server should not ignore but handle these requests whenever you're attempting to do cross origin requests.
CORS Support for Google App Engine in your app.yaml:
One important use of this feature is to support cross-origin resource sharing (CORS), such as accessing files hosted by another App Engine app.
For example, you could have a game app mygame.appspot.com that accesses assets hosted by myassets.appspot.com. However, if mygame attempts to make a JavaScript XMLHttpRequest to myassets, it will not succeed unless the handler for myassets returns an Access-Control-Allow-Origin: response header containing the value http://mygame.appspot.com.
handlers:
- url: /images
static_dir: static/images
http_headers:
Access-Control-Allow-Origin: http://mygame.appspot.com
Note: if you wanted to allow everyone to access your assets, you could use the wildcard '*', instead of http://mygame.appspot.com.

Kubernetes and AAD authentication

On configured AKS there is docker container with application that is using AAD authentication.
Based on this article there is also configured ingress. API is working well.
When I add to Azure Active Directory application registration reply URL with https prefix I receive error "The reply url specified in the request does not match the reply urls configured for the application". And I see that in browser address line redirect_uri is starting with http.
When I add reply URL that is starting with http, then I receive "Exception: Correlation failed".
What I have tried: Add to ingress.yaml setting ingress.kubernetes.io/force-ssl-redirect: "true"
May be there is some way to force ingress run https instead of http, or there might be some AAD redirect configuration? Any ideas?
UPDATE 2: Probably http redirect is because of ADAL.
PS: Was able to find similar topic without an answer
UPDATE3:
I have decided not to use nginx as ingress. Instead I am using now Load balancer. Soon it would be possible to use Azure Application Gateway Ingress Controller
Have you tried this?
By default the controller redirects HTTP clients to the HTTPS port 443 using a 308 Permanent Redirect response if TLS is enabled for that Ingress.
This can be disabled globally using ssl-redirect: "false" in the NGINX config map, or per-Ingress with the nginx.ingress.kubernetes.io/ssl-redirect: "false" annotation in the particular resource.
More information on this on the Ingress documentation link.
You have to make a decision whether to use HTTPS or not. If this is just the start of a development cycle, start without it and get auth to work - but implement HTTPS as soon as possible.
AAD supports both http and https, but of course, the reply urls must be added to the application registration respectively.
As #mihail-stancescu says, ssl-redirect must be set to false, if you choose not to use HTTPS. In addition to this, you also have to ensure that your app does not make the redirect from HTTP to HTTPS.
Using curl with -L -k and -v options will give you a lot of information on what is actually happening with your requests.
When the http/https thing is solved, you have to remove any rewrite annotations you have in your ingress. (e.g. ingress.kubernetes.io/rewrite-target: / should be removed).
Now, if your ingress path to the service in question is e.g. /myservice, then the reply-url should also have that part of the path added ([host]/myservice/signin-oidc) - both in the AAD application registration and in the configuration of your app. (The path in the config should not contain the host)
If you are using https, then you must also have a proper certificate. You can use the free LetsEncrypt (https://letsencrypt.org/) in conjunction with KubeLego (https://github.com/jetstack/kube-lego), where you can find some nice examples on how to implement it.

How to properly enable HTTPS on App Engine flex environment and Go?

I am trying to enable HTTPS on my Go App deployed to GAE flex environment. I have my custom domain successfully mapped, and am using Google-managed SSL certificates. I have app.yaml configured to redirect HTTP to HTTPS as follows:
handlers:
- url: /.*
script: _go_app
secure: always
Now there are two problems that I haven't been able to resolve so far.
First, the above configuration is supposed to redirect HTTP traffic to HTTPS, but apparently it is not happening.
Second, when I add https:// in the url box, I see three different behavior on Firefox, Chrome, and Edge. Edge identifies the website as secure, Firefox marks the website as secure connection, but says that it "has blocked parts of this page that are not secure", and surprisingly Chrome marks the website as Not secure (though it says certificate is valid!).
With these symptoms I was wondering if I should take additional steps to make redirecting and SSL work for my website? Specifically, I would like to know with App Engine, and managed SSL enabled:
Should I continue serving pages on HTTP using http.ListenAndServe(..), or need to switch to http.ListenAndServeTLS(..)?
In my Go app should I redirect HTTP to HTTPS? or the above setting is expected to work just fine?
Thanks in advance for your help and advice.
PS:
Trying out with different suggestions, I added Strict-Transport-Security: max-age=31536000; includeSubDomains to handlers' response. Does not seem if this helped with redirection either.
EDIT/PARTIAL ANSWER:
According to this documentation, under Authentication changes, the secure and login handlers are deprecated. The documentation suggests using Strict-Transport-Security or X-Forwarded-Proto instead.
I am using Strict-Transport-Security on the server side to enrich my response header:
func (h *STLHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
w.Header().Add("Strict-Transport-Security", "max-age=63072000; includeSubDomains")
h.nextHandler.ServeHTTP(w, req)
}
I was wondering if I am using this header in the right place?
For the second set of my problems I realized I have mixed content on my page. My mixed content was a http link to a set of fonts. When I fixed the mixed content, i.e. changed http to https, both Chrome and Firefox security warnings disappeared. You may also find this page Avoiding the Not Secure Warning in Chrome useful on this matter.
You need to check your app using:
http://[YOUR_PROJECT_ID].appspot.com
Or if you nedd HTTPS:
https://[YOUR_PROJECT_ID].appspot.com
If you want your own certificate you will need to upload it and then be available to use: https://your-domain.tld
From the docs:
For APIs that will be hosted on App Engine flexible environment, you must use the appspot.com domain, and the service name must be in the following format:
YOUR_PROJECT_ID.appspot.com
When you deploy your API to App Engine, a DNS entry with a name in the format YOUR_PROJECT_ID.appspot.com is created automatically.
For APIs that will be hosted on Compute Engine, Kubernetes Engine, or Kubernetes, you must use the cloud.goog domain, and the service name must be in the following format:
YOUR_API_NAME.endpoints.YOUR_PROJECT_ID.cloud.goog
Or you could just put a CDN in front like Cloudflare which will do all the SSL termination for you and if required redirect all HTTP to HTTPS

Authenticating a user in static_dir single-page-app so that it can call sibling GAE APIs

I have a React app that is being served on GAE via a static directory.
app.yaml:
- url: /my_admin_app
static_dir: admin_app
login: required
secure: always
When accessing via browser, GAE presents a login page as expected before continuing to the React app.
Because the React app is completely separate from the GAE app that is also running, I need the web app to call APIs that should require auth, as they control sensitive data.
The React app is calling sensitive APIs behind this URL:
app.yaml:
- url: /admin/.*
login: required // this causes a login page to be sent instead of data
script: main.app
secure: always
Is there a better way to serve my static files such that login isn't required again? Or is there a way to pass along the auth info when GAE presents its own login page?
I've learned that when Google presents the login, it passes along the auth cookie to the following web page.
Then, any requests that the page makes using fetch should specify that the cookie should be passed along with that request.
From the Mozilla docs: https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch
By default, fetch won't send or receive any cookies from the server, resulting in unauthenticated requests if the site relies on maintaining a user session (to send cookies, the credentials init option must be set).
So to make sure the auth gets passed on:
// to only pass to to same origin endpoints
fetch('/endpoint', {credentials:'same-origin'}).then(/*..*/)
// to pass without restriction
fetch('/endpoint', {credentials:'include'}).then(/*..*/)

Opensso with SSL Configuration issue in F5 Load Balancers

We are having a web application architecture where our application EAR is deployed in appServer configured with non-ssl Http Port Listener. Every request is routing via F5 Load Balancer-> Web Server-> App Server.
In Load Balancer, we have set an iRule where every Http Request is forwarded to Https set on port 443 and our application is working fine. Now we are trying to implement a SSO using OpenSSO federation solution and SAML Technology. we have deployed the opensso with the non-ssl http listener configuration in our app server.
now when we try to access the opensso using the url xhttp://domain_name/opensso(dummy protocol), it is redirected as per iRule set on the Load Balancer as xhttps://domain_name/opensso. But in the appearing configuration page of opensso, the server URL is populated as xhttp://domain_name only instead of xhttps://domain_name. Likewise, the same approach is followed to populate all the URL properties throughout the opensso configuration. So when I tried to generate the metadata using ssoadm GUI, In the form action attribute the url is formed as 'http' and the request method is passed as 'POST' only as per Opensso convention. But when it is redirected to 'https' as per the Load Balancer Rule the Request method is passed as 'GET' instead of post and the opensso validation fails and throwing the error as 'HTTP Post Protocol is required.
So the issue here is, By default the opensso URL properties should be populated with "https" instead of "http". I would like to know what is the wrong configuration done here. how we could resolve this issue? Thanks.
I think that you will find that the answer actually lies within your application server, not the application itself. You need to indicate to the servlet that it is being proxied, and that it is responsible for creating URLs with the HTTPS scheme, not HTTP.
If you're using Tomcat or a derivative, you can modify the server.xml to include the following:
proxyPort="443"
proxyName="www.domain_name.com"
scheme="https"
secure="true"
You can configure the load balancer to redirect to https with a 307 http status code which informs the client to use the original request method. If POST was the original request method then following the redirect the client will continue to use POST instead of a GET.
HTTP::respond 307 Location "https://[HTTP::host][HTTP::uri]"

Resources