{"id":90,"date":"2022-11-07T23:33:23","date_gmt":"2022-11-07T23:33:23","guid":{"rendered":"https:\/\/blogs.oregonstate.edu\/mike\/?p=90"},"modified":"2022-11-08T16:16:44","modified_gmt":"2022-11-08T16:16:44","slug":"cors-and-https","status":"publish","type":"post","link":"https:\/\/blogs.oregonstate.edu\/mike\/2022\/11\/07\/cors-and-https\/","title":{"rendered":"CORS and HTTPS"},"content":{"rendered":"\n<p>\u00af\\_(\u30c4)_\/\u00af<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"626\" height=\"366\" src=\"https:\/\/osu-wams-blogs-uploads.s3.amazonaws.com\/blogs.dir\/5982\/files\/2022\/11\/HTTP-To-HTTPS.png\" alt=\"\" class=\"wp-image-97\" srcset=\"https:\/\/osu-wams-blogs-uploads.s3.amazonaws.com\/blogs.dir\/5982\/files\/2022\/11\/HTTP-To-HTTPS.png 626w, https:\/\/osu-wams-blogs-uploads.s3.amazonaws.com\/blogs.dir\/5982\/files\/2022\/11\/HTTP-To-HTTPS-300x175.png 300w\" sizes=\"auto, (max-width: 626px) 100vw, 626px\" \/><\/figure><\/div>\n\n\n\n<p>For our full stack web application project, my capstone team has chosen an application architecture that consists of hosting the front-end application (user interface) and back-end application (REST API and database) separately on different servers, resulting in two URLs with different domain names. This configuration has the advantages of enforcing the design principal of <a rel=\"noreferrer noopener\" href=\"https:\/\/en.wikipedia.org\/wiki\/Separation_of_concerns\" target=\"_blank\">separation of concerns<\/a> and allowing for greater development and deployment flexibility. We are using A<a rel=\"noreferrer noopener\" href=\"https:\/\/aws.amazon.com\/amplify\/\" target=\"_blank\">WS Amplify<\/a> to deploy and host the front-end application built with <a rel=\"noreferrer noopener\" href=\"https:\/\/reactjs.org\/\" target=\"_blank\">React<\/a>. For the back-end, built using Java and <a rel=\"noreferrer noopener\" href=\"https:\/\/spring.io\/projects\/spring-boot\" target=\"_blank\">Spring Boot<\/a>, we are using <a rel=\"noreferrer noopener\" href=\"https:\/\/aws.amazon.com\/elasticbeanstalk\/\" target=\"_blank\">AWS Elastic Beanstalk<\/a> to orchestrate deployment and hosting using various services such as EC2 and Elastic Load Balancing. While Elastic Beanstalk could also be used to provision our PostgreSQL relational database, we have chosen to separate this component instead, and we have manually provisioned the database using <a rel=\"noreferrer noopener\" href=\"https:\/\/aws.amazon.com\/rds\/\" target=\"_blank\">Amazon RDS<\/a>. This allows us even greater flexibility, with the ability to deploy back-end changes without any unneeded impact to the database layer.<\/p>\n\n\n\n<p>Although we are using two AWS services for deploying and hosting our front-end and back-end, each application ends up running on different compute instances with different domain names for accessing each on the internet. While there are benefits to this separation, there have been some local development and production environment issues that needed to be addressed. The first is <a rel=\"noreferrer noopener\" href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/HTTP\/CORS\" target=\"_blank\"><strong>Cross-Origin Resource Sharing<\/strong><\/a> (CORS). CORS is a \u201cmechanism that allows restricted resources on a web page to be requested from another domain outside the domain from which the first resource was served.\u201d This specification also applies to cross-origin requests made to our back-end REST API, but such requests are not enabled by default in our application framework, resulting in a blocked request message indicating that an <code>Access-Control-Allow-Origin<\/code> header is missing on the requested resource. We actually discovered this restriction while running the front-end app locally during development, which was making requests to the back-end running on AWS. Allowing cross-origin requests involves some back-end application <a rel=\"noreferrer noopener\" href=\"https:\/\/spring.io\/blog\/2015\/06\/08\/cors-support-in-spring-framework\" target=\"_blank\">configuration<\/a>, and addressing this issue for local development also resolves it when the application is running in production on AWS, as both environments use cross-origin requests.<\/p>\n\n\n\n<p>Another issue we ran into was <a rel=\"noreferrer noopener\" href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/Security\/Mixed_content\" target=\"_blank\"><strong>mixed content<\/strong><\/a>. AWS Amplify hosts our front-end application with a domain using <a rel=\"noreferrer noopener\" href=\"https:\/\/en.wikipedia.org\/wiki\/HTTPS\" target=\"_blank\">HTTPS<\/a>, which uses a secure protocol (<a rel=\"noreferrer noopener\" href=\"https:\/\/en.wikipedia.org\/wiki\/Transport_Layer_Security\" target=\"_blank\">TLS<\/a>) to encrypt the web server connection and any requests and responses to\/from the server. Elastic Beanstalk, on the other hand, uses HTTP by default. While attempting to make requests from the front-end pages served over HTTPS to the back-end using unencrypted HTTP, such requests are blocked by the browser. This is a security feature to protect against <a rel=\"noreferrer noopener\" href=\"https:\/\/en.wikipedia.org\/wiki\/Man-in-the-middle_attack\" target=\"_blank\">man-in-the-middle<\/a> attacks and protect other vulnerabilities. While there may be various workarounds for getting past mixed-content blocking, we determined the best strategy to resolve this issue would be to also serve the back-end content over HTTPS instead of HTTP. We would come to find out this is not as straight forward as resolving the CORS issue.<\/p>\n\n\n\n<p><strong>Use a custom domain<\/strong><\/p>\n\n\n\n<p>There are three different ways to use HTTPS with Elastic Beanstalk. Two of these methods involve setting up our own SSL certificate. Fortunately, I just so happened to already have a custom domain configured with a certificate on AWS. This allowed us to use the third option, and the easiest one, which is route traffic from the custom domain to the <a rel=\"noreferrer noopener\" href=\"https:\/\/docs.aws.amazon.com\/elasticloadbalancing\/latest\/application\/introduction.html\" target=\"_blank\">Application Load Balancer<\/a> (ALB) configured for our back-end application by Elastic Beanstalk. <a rel=\"noreferrer noopener\" href=\"https:\/\/aws.amazon.com\/route53\/\" target=\"_blank\">Amazon Route 53<\/a> is a Domain Name Service (DNS) that allows us to do just that.<\/p>\n\n\n\n<p><strong>Setup SSL<\/strong><\/p>\n\n\n\n<p>As mentioned, we already have a certificate, and it is configured with <a rel=\"noreferrer noopener\" href=\"https:\/\/aws.amazon.com\/certificate-manager\/\" target=\"_blank\">AWS Certificate Manager<\/a>.  We just need to ensure our certificate is set up with our domain name, both with and without &#8220;www&#8221; in front.  <\/p>\n\n\n\n<p><strong>Add a secure connection to our backend application<\/strong><\/p>\n\n\n\n<p>On the EC2 Dashboard in the AWS management console, in the Load Balancers section, we already have an HTTP listener set up for our Application Load Balancer.  We can also add an HTTPS listener, which uses encrypted connections between clients and the load balancer:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"186\" src=\"https:\/\/osu-wams-blogs-uploads.s3.amazonaws.com\/blogs.dir\/5982\/files\/2022\/11\/Screenshot-from-2022-11-07-15-18-46-1024x186.png\" alt=\"\" class=\"wp-image-93\" srcset=\"https:\/\/osu-wams-blogs-uploads.s3.amazonaws.com\/blogs.dir\/5982\/files\/2022\/11\/Screenshot-from-2022-11-07-15-18-46-1024x186.png 1024w, https:\/\/osu-wams-blogs-uploads.s3.amazonaws.com\/blogs.dir\/5982\/files\/2022\/11\/Screenshot-from-2022-11-07-15-18-46-300x55.png 300w, https:\/\/osu-wams-blogs-uploads.s3.amazonaws.com\/blogs.dir\/5982\/files\/2022\/11\/Screenshot-from-2022-11-07-15-18-46-768x140.png 768w, https:\/\/osu-wams-blogs-uploads.s3.amazonaws.com\/blogs.dir\/5982\/files\/2022\/11\/Screenshot-from-2022-11-07-15-18-46.png 1205w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>A security group is associated with the load balancer to control traffic that is allowed to reach, as well as leave the ALB.  Since we&#8217;ve configured the load balancer to listen for HTTPS requests, we need to also add an Inbound Rule to the security group to allow incoming HTTPS traffic:  <\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"189\" src=\"https:\/\/osu-wams-blogs-uploads.s3.amazonaws.com\/blogs.dir\/5982\/files\/2022\/11\/Screenshot-from-2022-11-07-15-23-49-1024x189.png\" alt=\"\" class=\"wp-image-94\" srcset=\"https:\/\/osu-wams-blogs-uploads.s3.amazonaws.com\/blogs.dir\/5982\/files\/2022\/11\/Screenshot-from-2022-11-07-15-23-49-1024x189.png 1024w, https:\/\/osu-wams-blogs-uploads.s3.amazonaws.com\/blogs.dir\/5982\/files\/2022\/11\/Screenshot-from-2022-11-07-15-23-49-300x55.png 300w, https:\/\/osu-wams-blogs-uploads.s3.amazonaws.com\/blogs.dir\/5982\/files\/2022\/11\/Screenshot-from-2022-11-07-15-23-49-768x142.png 768w, https:\/\/osu-wams-blogs-uploads.s3.amazonaws.com\/blogs.dir\/5982\/files\/2022\/11\/Screenshot-from-2022-11-07-15-23-49.png 1371w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p><strong>Conclusion<\/strong><\/p>\n\n\n\n<p>Deploying and hosting our full stack application provided many learning opportunities for our team.  We are able to use various AWS services that are new to us, and we encountered issues that required our combined resourcefulness to resolve.  These are high-level steps we&#8217;ve taken to configure our application to allow Cross-Origin Resource Sharing and to enable HTTPS for our back-end REST API to satisfy the security concern of mixed-content resource blocking.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>\u00af\\_(\u30c4)_\/\u00af For our full stack web application project, my capstone team has chosen an application architecture that consists of hosting the front-end application (user interface) and back-end application (REST API and database) separately on different servers, resulting in two URLs with different domain names. This configuration has the advantages of enforcing the design principal of [&hellip;]<\/p>\n","protected":false},"author":12740,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-90","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"_links":{"self":[{"href":"https:\/\/blogs.oregonstate.edu\/mike\/wp-json\/wp\/v2\/posts\/90","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blogs.oregonstate.edu\/mike\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blogs.oregonstate.edu\/mike\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blogs.oregonstate.edu\/mike\/wp-json\/wp\/v2\/users\/12740"}],"replies":[{"embeddable":true,"href":"https:\/\/blogs.oregonstate.edu\/mike\/wp-json\/wp\/v2\/comments?post=90"}],"version-history":[{"count":10,"href":"https:\/\/blogs.oregonstate.edu\/mike\/wp-json\/wp\/v2\/posts\/90\/revisions"}],"predecessor-version":[{"id":108,"href":"https:\/\/blogs.oregonstate.edu\/mike\/wp-json\/wp\/v2\/posts\/90\/revisions\/108"}],"wp:attachment":[{"href":"https:\/\/blogs.oregonstate.edu\/mike\/wp-json\/wp\/v2\/media?parent=90"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blogs.oregonstate.edu\/mike\/wp-json\/wp\/v2\/categories?post=90"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blogs.oregonstate.edu\/mike\/wp-json\/wp\/v2\/tags?post=90"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}