Opensso with SSL Configuration issue in F5 Load Balancers - saml-2.0

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]"

Related

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.

spring boot with react frontend oauth2 proxy CORS issue

I'm able to build my own oauth2 server following this example
I then created my own client side app with frontend being react. I specifically used facebook's create-react-app to get a quick start point.
I also found that in order to run the frontend in dev mode while connecting to backend api, I need to have a proxy added in the package.json file.
Now I have everything at hand:
The oauth2 server running on "localhost:8080"
The client app api running on "localhost:9090"
The frontend running in dev mode on "localhost:3000" with proxy set to connecting api port "9090"
When I try to connect to "localhost:3000", I always get the following error:
Failed to load http://localhost:9090/login: Redirect from 'http://localhost:9090/login' to 'http://localhost:8080/oauth/authorize?client_id=acme&redirect_uri=http://localhost:9090/login&response_type=code&scope=read%20write&state=qbV8P2' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:3000' is therefore not allowed access.
If I run "yarn build" and let spring boot serve the frontend static files, then if I access "localhost:9090", I will be properly redirected to the login page from the oauth2 server.
I've tried to allow "localhost:3000" by editing cors mapping from spring boot but this problem is still here.
As a side note, If I get authenticated by accessing "localhost:9090", and acquired the session cookie, then I can access protected resource by using "localhost:3000". It's just if I am not authenticated in the first place, then instead of being redirected to the login page, I always get the CORS error.
Any help would be appreciated.
CORS is basically a way to determine if it is safe to grant access to restricted resource on a web page when requested from another domain. I am not sure, how does it works when you let spring boot serve your frontend static files. But you would simply have to grant permissions to your frontend server at http://localhost:3000 to access restricted resources at http://localhost:8080.
For e.g., if your request header looks like following:
Access-Control-Allow-Origin:http://localhost:3000
Access-Control-Request-Method: POST
Access-Control-Request-Headers: <your custom headers>
Then, server rules must be:
Access-Control-Allow-Origin:http://localhost:3000
Access-Control-Request-Method: POST, GET, DELETE, PUT
Access-Control-Request-Headers: <your custom headers>
Please note that keeping any parameter as * won't work.
Please let me know if it helps!

Why am I receiving a cross-origin error when using the react-stormpath LoginForm component?

I followed the instructions found in the readme in the stormapth-sdk-react github respository to set up a basic login form. The form displays, but I am immediately greeted by errors in the console:
XMLHttpRequest cannot load https://{redacted}.apps.stormpath.io/me. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:3000' is therefore not allowed access. The response had HTTP status code 403.
I get an identical error for the login endpoint.
The Client API Guide indicates that client endpoints have to be configured to allow traffic from a particular domain, but does not provide any instructions for how to do this:
Applications that use the Client API have two relevant configuration parameters, both found on your Application’s page in the Stormpath Admin Console:...
Authorized Callback URIs: This list should include any URIs that your users will be returned to after they have completed authentication with an outside provider, for example as a part of the social login flow. For example, if you do not specify a redirect URI when you kick off the social login flow, the user will be redirected the first URI in this list.
Authorized Origin URIs: This list should include the application’s URL, or whatever URL will be included in the Origin header of requests sent to the Client API.
What do I need to do to get this working?
To fix this, you can login to https://api.stormpath.com, navigate to Applications > My Application, and modify the Authorized Origin URIs to include http://localhost:3000.
Stormpath seems to use a pretty similar setup to many API services. Like the directions say, go to your Stormpath Admin Console, and put your hostname (http://localhost:3000) in the relevant fields for both 1. and 2.
Doing so tells the Stormpath API to allow data to be sent to your application.
The Cross-Origin Resource Sharing (CORS) mechanism gives web servers cross-domain access controls, which enable secure cross-domain data transfers.
As the server you are using (for react) differs from the server you are requesting data(node or something else). (even the subdomain or port matters)
index.js: (server)
const cors = require('cors');
..
..
app.use(cors());
for more info about using cors: npm cors

bypass https to request non-secure link

I have a bit of an issue that I can't seem to wrap my head around. The app/site is secured complete with a SSL Certificate, but we need to send an $http request with angular to a non-secured api end-point. The service does not offer a https solution and everytime we try sending the request, our server blocks it because it is not secured. Is there anyway to get around this? A way to "whitelist" the domain name or something?
Information: Server is running Nginx and the request is being made via $http angularjs.

angular OPTIONS http preflight on "Same Domain"?

I am currently confused about how angular's (jquery) preflight OPTIONS call is "selected" or chosen to perform before a request.
I have a normal RESTful api call (api.domain.co)
I have created a host entry 127.0.0.1 local.domain.co in my hosts file /etc/hosts.
I've created self-signed certificate:
http://www.akadia.com/services/ssh_test_certificate.html
I've configured the certs in my mac as trusted:
http://abetobing.com/blog/port-forwarding-mac-os-yosemite-81.html
I've configured my Yosemite Port Forwarding Rules:
http://abetobing.com/blog/port-forwarding-mac-os-yosemite-81.html
I understand that from the browser's perspective (Chrome):
I have an angular app being loaded from https://local.domain.co with a trusted certificate that has a call to https://api.domain.co/user everything looks green with the cert, and I still get a preflight OPTIONS call to my api.domain.co server which is a node resitfy server with CORS support
Everything is Working... BUT
I want to get rid of the OPTIONS preflight Any pointers?
unfortunately subdomain still affected by preflight rule so if you want to remove OPTIONS you can either using jsonp or have the same subdomain for both the site & api.
You can't use localhost. I had to create an entry in my host file to associate 127.0.0.1 to an arbitrary name like mackbook. Then it should work for you.

Resources