Forum Moderators: phranque

Message Too Old, No Replies

RewriteCond for SSL login page

         

perlion

12:06 am on Mar 30, 2008 (gmt 0)

10+ Year Member



Hello. I need some help with rewrite rules for redirecting from https to http. I have tried numerous examples, the latest here.
[webmasterworld.com...]

What I need to do is have my login_form go to https, which it does with the following config in http.conf.

However, when I log in and then log out or go to other areas of site, it stays in https. Does anything look wrong in this config?

p.s. The virtualhostbase and virtualhostroot stuff is because I run a Zope server and have a virtual site location, where example.com is my server and virtual_site is my website. Login_form is a webpage.

I have all of this in httpd.conf. With Apache 2 should any of this go into my ssl.conf where I have 443 redirect set up?

httpd.conf

<IfModule mod_rewrite.c>
RewriteEngine On
# If https request
rewritecond %{SERVER_PORT} ^443$
# redirect non-login requests to HTTP
RewriteRule ^/(.*)login_form/(.+)$ http://example.com/virtual_site/login_form/$1 [R=301,L]
RewriteRule ^/(.*) [localhost:8080...] [L,P]

ssl.conf

RewriteRule ^/(.*) [localhost:8080...] [L,P]

Thank You for anyone that can help me out.

jdMorgan

2:53 am on Mar 30, 2008 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



I don't know what you're doing with the proxy pass-through stuff, but the basic idea is that you need to detect SSL and non-SSL protocol and the "login_form" URL-path-part, and redirect if the combination of SSL/non-SSL protocol and login/non-login URL-path state is incorrect. This is fundamentally an http-to-https or https-to-http redirect, using the same hostname and URL-path; Only the protocol should be changed. Your proxy function, if intentional and if needed, should be a separate step.

httpd.conf:


RewriteEngine on
#
# If not HTTPS request
RewriteCond %{SERVER_PORT} !^443$
# redirect login requests to HTTPS
RewriteRule ^/(([^/]+/)*)login_form/(.*) https://%{SERVER_NAME}/$1/login_form/$3 [R=301,L]

ssl.conf:

RewriteEngine on
#
# If HTTPS request
RewriteCond %{SERVER_PORT} ^443$
# and if not login form
RewriteCond %{REQUEST_URI} !^/([^/]+/)*login_form/
# redirect to HTTP
RewriteRule ^/(.*) http://%{SERVER_NAME}/$1 [R=301,L]

I included the port number checks for completeness; They may not be strictly required. Also note that if you're using virtualhosts, you may wish to use %{HTTP_HOST} instead of %{SERVER_NAME} to build the redirection URL hostname. Otherwise, your 'users' may be unable to change to their preferred "www" or "non-www" canonical hostname at the .htaccess level without asking you to change httpd.conf for them.

Also note that the two regex patterns resembling ^/([^/]+/)*login_form/ above assume that a subdirectory or subdirectories precede "login+form" (it wasn't clear if this was a good assumption). This is an attempt to avoid using the greedy, promiscuous, and inefficient ".*" pattern for performance reasons. (Note that almost *none* of Engelschall's examples use ".*" as pattern-parts)

Jim

perlion

5:21 pm on Mar 30, 2008 (gmt 0)

10+ Year Member



Thank You Jim for helping me out. You seem to be very knowledgeable on this subject and I'm lucky to have found this forum.

I tried what you had posted and some variants of parts of the code.

I'm still not able to get it to log out of https.

With my original httpd.conf and ssl.conf, I can get to /login_form in https with a redirect.

httpd.conf

<IfModule mod_rewrite.c>
RewriteEngine On


#This Works for redirect
RewriteRule ^/(.*)/login_form(.*) [example.com...] [NC,R=301,L]

RewriteRule ^/(.*) [localhost:8080...] [L,P]
</IfModule>

ssl.conf

<IfModule mod_rewrite.c>
RewriteEngine On

RewriteRule ^/(.*) [localhost:8080...] [L,P]
</IfModule>

When I put your code above my RewriteRule ^/(.*) [localhost:8080...] parts, and disable this redirect rule, I can get to the site but it doesn't go into https for login_form.

#This Works for redirect
RewriteRule ^/(.*)/login_form(.*) [example.com...] [NC,R=301,L]

I tried putting my redirect rule above in place of your rule below and I can get to site but get "The page cannot be displayed" for /login_form

# redirect login requests to HTTPS
RewriteRule ^/(([^/]+/)*)login_form/(.*) [%{SERVER_NAME}...] [R=301,L]

More background on site. I run Plone CMS on top of a Zope server. I proxy thru Apache2 on [localhost:8080...] via VirtualHostMonster.

That is what the Virtualhost base and Virtualhostroot is all about.

Basically (from [wiki.zope.org...]

RewriteRule ^/zopesite/(.*) \
[127.0.0.1:8080...]
http/%{SERVER_NAME}:80/VirtualHostRoot/_vh_zopesite/$1 [L,P]

The first part of this (RewriteRule?) starts the command, after that come three distinct parts:

* the expression that tries to match on the original request URL ^/zopesite/(.*)
* the expression that rewrites this URL when a match exists [127.0.0.1:8080...]
* the parameters that allow to alter some of the behaviour [L,P]

All that said, I can tweak the # redirect login requests to HTTPS part
but the problem is when trying to go back to http. I see the logic in your code but I need to find the right rules on the bits below.

# If HTTPS request
RewriteCond %{SERVER_PORT} ^443$
# and if not login form
RewriteCond %{REQUEST_URI} !^/([^/]+/)*login_form/
# redirect to HTTP
RewriteRule ^/(.*) [%{SERVER_NAME}...] [R=301,L]

What do the regex $1 $2 and $3 do?

Also if you want to try the site do you have e-mail?

jdMorgan

6:31 pm on Mar 30, 2008 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



> What do the regex $1 $2 and $3 do?

A review of the documentation [httpd.apache.org] is much-needed before proceeding... See the phrase "back-references."

> See the site.

Not helpful or productive, I'm afraid. I'd need a shell account, a lot more knowledge of the "back-end stuff" you're using, and, well, a contract. Again, you're mixing proxy functions with redirects, and that's likely part of the problem. The code I posted demonstrates how to get in and out of SSL according to the criteria you specified, and that's all I intended; This is a general discussion forum, not a developers help desk.

You'll need to read the docs and adapt the methodology demonstrated by the example code to suit your needs, paying particular attention to putting the right code snippets into the right directory, file, <container>, -- and even server.

Jim

perlion

7:09 pm on Mar 30, 2008 (gmt 0)

10+ Year Member



Thank You for you help.

perlion

10:47 pm on Mar 31, 2008 (gmt 0)

10+ Year Member



Jim, I really appreciate your knowledge and insight. Out of desperation I probably was asking for too much from you. But with your direction I have solved the problem and learned some things along the way.

It may be a little sloppy but it works:

httpd.conf

<IfModule mod_rewrite.c>
RewriteEngine On

#This Works for HTTPS redirect

# If not HTTPS request
RewriteCond %{SERVER_PORT} !^443$
# redirect login requests to HTTPS
RewriteRule ^/(.*)/login_form(.*) [example.com...] [NC,R=301,L]
RewriteRule ^/(.*)/service-call-request(.*) [example.com...] [NC,R=301,L]

RewriteRule ^/(.*) [localhost:8080...] [L,P]

</IfModule>

ssl.conf

<IfModule mod_rewrite.c>
RewriteEngine On

# If HTTPS request
RewriteCond %{SERVER_PORT} ^443$
# and if not login form
RewriteCond %{REQUEST_URI} !^/(.*)/login_form
RewriteCond %{REQUEST_URI} !^/(.*)/service-call-request
# redirect to HTTP
RewriteRule ^/(.*) http://www.example.com/$1 [R=301,L]

RewriteRule ^/(.*) [localhost:8080...] [L,P]

# use RewriteLog to debug problems with your rewrite rules
# disable it after you found the error our your harddisk will be filled *very fast*
RewriteLog "/var/log/apache2/rewrite_log"
RewriteLogLevel 3

</IfModule>

For anyone else who has this problem, This config works with Plone on Zope server with Apache2 as a front-end.

Thanks again Jim!

jdMorgan

1:58 pm on Apr 1, 2008 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



You can clean up these two lines:

RewriteCond %{REQUEST_URI} !^/(.*)/login_form
RewriteCond %{REQUEST_URI} !^/(.*)/service-call-request

making them

RewriteCond %{REQUEST_URI} !/login_form
RewriteCond %{REQUEST_URI} !/service-call-request

Since no back-reference is made to the path-prefix, you can use an unanchored pattern to avoid making the regex parser do unnecessary work.

Glad you got it working! Until the contributors here get a teleportable WebmasterWorld over-your-shoulder cam and a lot more free time, the constraints of a forum venue mean that there's a limit to what we can do here. When a poster "takes ownership" of the problem as you did, things usually turn out well.

It's good to see that the solution did indeed lie with separating the redirection and proxy functions... :)

Jim