Redirect all http request to https requests using apigee

Not applicable

Hi,

I have a webservice with http url. I want to apply https on top of it using apigee and want to redirect all http requests coming for that webservice url into https requests and then process through apigee other message processors.

I understood that by removing <VirtualHost>default</VirtualHost> from the api proxy xml, it will not allow http request and <VirtualHost>secure</VirtualHost> is for allowing https requests to the API.

But i want to redirect http requests to https using some configuration. Please let me know.

Solved Solved
0 12 3,933
1 ACCEPTED SOLUTION

Yes, you can.

First, add back the VirtualHost "default" to allow inbound http.

Then you must add a condition that checks client.scheme and compares it to http. And in that case, execute a JS policy that computes the https redirect URL, and execute a RaiseFault policy to send it back. Something like this.

<PreFlow name="preflow">
  <Request>
     <Step>
       <Name>JS-SetSecureUrl</Name>
       <Condition>client.scheme = "http"</Condition>
     </Step>
     <Step>
       <Name>RF-Issue302Redirect</Name>
       <Condition>client.scheme = "http"</Condition>
     </Step>
  </Request>
</PreFlow>

The RF (RaiseFault) policy just sets a Header called "Location" to a specific value, determined by a context variable.

The JS (JavaScript) policy sets the context variable. To figure out the JavaScript you need, you can refer to this documentation, which describes how to re-assemble the inbound URL .

View solution in original post

12 REPLIES 12

Yes, you can.

First, add back the VirtualHost "default" to allow inbound http.

Then you must add a condition that checks client.scheme and compares it to http. And in that case, execute a JS policy that computes the https redirect URL, and execute a RaiseFault policy to send it back. Something like this.

<PreFlow name="preflow">
  <Request>
     <Step>
       <Name>JS-SetSecureUrl</Name>
       <Condition>client.scheme = "http"</Condition>
     </Step>
     <Step>
       <Name>RF-Issue302Redirect</Name>
       <Condition>client.scheme = "http"</Condition>
     </Step>
  </Request>
</PreFlow>

The RF (RaiseFault) policy just sets a Header called "Location" to a specific value, determined by a context variable.

The JS (JavaScript) policy sets the context variable. To figure out the JavaScript you need, you can refer to this documentation, which describes how to re-assemble the inbound URL .

Just be aware that by using a RaiseFault policy, your Analytics will display the 302's as Errors in the Error Dashboard. If you want to avoid this, use an AssignMessage and ensure no unnecessary policies are executed.

Really good point, Sean, thank you!

Hi,

Now, I am getting the response from http also by modifying the code as below

context.setVariable('target.url',req_url);

If I test https request from browser, then it is not showing me [Secure] before https ; but in http, it is not showing [Secure]. please let me know if it is proper or not.

code is as below:

JS:

var req_verb = context.getVariable('request.verb'); var req_scheme = context.getVariable('client.scheme'); var req_host = context.getVariable('request.header.host'); var req_request_uri = context.getVariable('request.uri'); var req_url = "https://" + req_host + req_request_uri; context.setVariable('target.url',req_url);

RF:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <RaiseFault async="false" continueOnError="false" enabled="true" name="RF-Issue302Redirect"> <DisplayName>RF-Issue302Redirect</DisplayName> <Properties/> <FaultResponse> <Set> <Headers/> <Payload contentType="text/plain"/> <StatusCode>500</StatusCode> <ReasonPhrase>Server Error</ReasonPhrase> </Set> </FaultResponse> <IgnoreUnresolvedVariables>true</IgnoreUnresolvedVariables> </RaiseFault>

secure-url-https.pngI tried both options -RaiseFault with JS and AssignMessage also. It's outputting the same result.

But i am not getting if it should change the url in the browser or not to https and add [Secure] or not like attached file for http request also.

Your RaistFault policy has a Status Code of 500.

You need to change this to 302 and set the Location header to be the URL you want to redirect to.

Wow 🙂 Finally it worked. Thanks @Sean Davis @Dino

Not applicable

@zalak pathak: Yes, you are right to make a proxy as inbound HTTPS, VirtualHost must be secure. i.e. <VirtualHost>secure</VirtualHost>

Configure 'target servers' for https under 'Environment Configuration'.

make sure SSLinfo enabled If you are using LoadBalancer/URL.

e.g:

<HTTPTargetConnection>

<Properties/>

<SSLInfo>

<Enabled>true</Enabled>

</SSLInfo>


<LoadBalancer>

<Server name="ProductsEndPoint">

<IsEnabled>true</IsEnabled> </Server>

</LoadBalancer>


<Path>/v1/api</Path>

<!-- <URL> https://edgemarket-prod.apigee.net/v1</URL>; -->

</HTTPTargetConnection>

Not applicable

Hi Zalak,

Your question is little confusing. Can you please write your requirement what you want to implement irrespective of apigee.

@Dinesh Kumar @Dino My question here is when i added Javascript and raisefault policy, it is giving the result in http request also, but it is not giving the [Secure] and change the URL in browser to https like in image.secure-url-https.png I am expecting this to happen in browser URL. Is this something which will not happen using this redirection code?

Configuring Apigee Edge to issue a 302 redirect will work if the browser invokes the endpoint managed within Apigee Edge as a regular page.

Some APIs are not invoked that way - for example, if you use jQuery in your browser-resident code to invoke an API with $.ajax() or something similar, then the jQuery library may not follow the 302, and even if it does, that will not update the browsers URL address bar. If you use react or angular - the same thing applies. Whatever client-side ajax library you use, it probably won't update the browser's URL Address bar. This is by design and intent.

To understand more about this, you might want to read up on AJAX. And I apologize if this is not helpful; if that's the case I'm just not understanding your question clearly.

Thanks @Dino for your inputs.