Want to win a PS4? Go Premium and enter to win our High-Tech Treats giveaway. Enter to Win

x
?
Solved

How to limit MOD_REWRITE to initial request - pass through on redirect ?

Posted on 2004-10-22
15
Medium Priority
?
446 Views
Last Modified: 2010-05-18
Hi All,

Am I using mod_rewrite correctly ?
Or should I be pursuing some other solution ?

* I'd like to provide basic authentication/access control to static pages/files in apache.
* Currently our security/users/ACP etc. are all managed by an application in WebSphere/DB2.  I don't want to duplicate all this information for Apache -- though eventually we will move to LDAP and one central store.

** My hope is to use mod_rewrite (for the short-term to):
1) redirect all URL requests for a certain directory to a servlet;  with the original requested url now appended as a parameter to the servlet:
http://myservlet/?url=http://myOrigURL

2) the servlet checks if the user is logged in (websphere login) -- if not they are redirected to the right forms etc.etc. if successful -- the user is then redirected (response.sendRedirect()) back to the original URL they requested.

3) I figured I could use a condition:
RewriteCond %{REMOTE_ADDR} !localHost

To make sure I'm NOT trapped into an endless URL redirect situation.
However, my servlet response.sendRedirect preserves the original "requesters" IP -- so I can't tell if the request is coming from:
   a) my servlet using a redirect or
   b) directly from an unauthenticated client ?

Servlet - "forward" commands can only forward within the context of the servlet container (i.e. cannot forward to an external URL ?)

My Question:
** Can mod_rewrite work in this situation -- or am I wasting time ??
** Is there some kind of production worthy apache module (currently looking at mod_auth_any) that can help me delegate apache authentication to existing servlet code I have ??

Hope someone can help me out.

Please see rewrite rules I'm using below....


Thanks

Frank

From....MyMOD_REWRITE.conf:
RewriteEngine on
RewriteLog "D:\WebSphere\HTTPServer\logs\rewrite.log"
RewriteLogLevel 4
RewriteCond %{REMMOTE_ADDR} !httpServerHost [OR]
RewriteCond %{REMMOTE_ADDR} !xxx.xxx.xxx.xxx
RewriteRule ^(.*)/download/(.*) http://host/webapp/servlet/forceLoginDirect?urlKey=%{REQUEST_URI}
##NOTE: Tried appending -- but don't really grok the following:
##[R]    and [R,L]
##[PT]  and  [PT,L]
##[P]    and  [P,L]
## Still URL loops endlessly on redirect from sevlet because
##%{REMOTE_ADDR} does not become the httpServerHost IP on redirect.
--------------------------

Note: These rules are specifed at the server level (i.e. NOT directory level)
But they are within context of a VirtualHost:

From....httpd.conf:
<VirtualHost xxx.xxx.xxx.xxx>
      ServerName www.ourdomain.com
      Include E:\WebSphere\HTTPServer\conf\MyMOD_REWRITE.conf
      Alias      /doc                  "E:\WebSphere\App/web/doc"
      etc.etc.
</VirtualHost>


I'd be eternally grateful for ANY feedback/thoughts.

Hope to hear from someone soon.....
Thanks
0
Comment
Question by:fmisa
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 8
  • 7
15 Comments
 
LVL 5

Expert Comment

by:mrielf
ID: 12383810
Hi!
I think you shold not redirect back to url in your servlet, instead serve the url content through your servlet if user is authenticated. (or use a regular html page for it)

Use Rewrite like this:

RewriteEngine on

## If the requested url is your servlet, then do nothing
RewriteRule ^/webapp/servlet/forceLoginDirect - [L]

## else do the redirection
RewriteRule ^(.*)/download/(.*) http://host/webapp/servlet/forceLoginDirect?urlKey=%{REQUEST_URI}

0
 
LVL 5

Expert Comment

by:mrielf
ID: 12383995
One more thing.

If you want to authenticate at downloads only, yo can use download protector scripts for it with combination rewrite rules (onyl exclude the script from rewriting like the servlet)

And always place the RewriteRule witch do the redirection at the end of rules

0
 

Author Comment

by:fmisa
ID: 12384129
I'll be a little red faced -- though happy to be on the right track finally -- if what you're saying works.....

The content I need to serve is on the same web server (application server) as my servlet -- but I though in order to "serve" this content (which could be file like pdf, doc etc. not just html) my servlet would have to:
* redirect() -> which get's me back to the endless URL redirect issue...
* forward() -> which I cannot do beyond the servlet's "context" ??
                     (i.e. I can't forward to "http://..." or "../../webapp/" only to "/webapp/.../.."

Am I missing something fundamental here ??

Thanks for replying......

Maybe I'm wrong ?
But I think I'm offering a huge number of points for this ?

Can you please a) supply source code snippet b) comment on other solutions if it turns out that mod_rewrite/servlet approach is not going to be able to work ?

Here's the scenario.....
1) User requests:
http://someHost/headoffice/downloads/someFile.xls

2) Apache mod_rewrite rules - redirect to:
http://someHost/webapp/servlet/forceLoginDirect?
     urlKey=/headoffice/downloads/someFile.xls&
     httpHost=someHost

3) My servlet - checks authentication - if OK - then executes the following:
    String redirectURI = request.getParameter("urlKey");
    String httpHost = request.getParameter("httpHost");    
    response.sendRedirect("http://"+httpHost+redirectURI);

4) Problem is - on redirect %{REMMOTE_ADDR} IP is still that of original "client" -- not my web/ApplicationServer ?
   So the following mod_rewrite condition: RewriteCond %{REMMOTE_ADDR} !httpServerHost
   does NOT prevent the endless URL redirection ??
   Forward is not possible from servlet - I think - beyond the servlets own directory tree/context.....

Hope I'm missing something obvious ??

Thanks for working this question with me....

0
Simplify Your Workload with One Tool

How do you combat today’s intelligent hacker while managing multiple domains and platforms? By simplifying your workload with one tool. With Lunarpages hosting through Plesk Onyx, you can:

Automate SSL generation and installation with two clicks
Experience total server control

 
LVL 5

Expert Comment

by:mrielf
ID: 12384330
After authentication check dont redirect to the original page. Redirect it to a dowload script instead.

What kind of Web language you using?

PHP is ok? (I can show you scrips for this in php)
0
 
LVL 5

Expert Comment

by:mrielf
ID: 12384388
And what you want? The link is opened in the window or force downlad files?
0
 

Author Comment

by:fmisa
ID: 12384550
I'm using JSP for scripting.... would you have a JSP example ?
0
 
LVL 5

Expert Comment

by:mrielf
ID: 12384613
My idea about to redirect to download script isn't good...
You must integrate two script in one (to prevent security issues)

Look at this component:

http://www.javazoom.net/jzservlets/download4j/download4j.html#overview

I think it will help you out...
0
 

Author Comment

by:fmisa
ID: 12384765
I will look at this product tonight.
However, I was hoping to let:
   * Apache take care of serving the content.
   * Servlet take care of the authentication
   * and mod_rewrite to switch between the two.....

Completely transparent to the end user.....

If I can't perform this using just apache/module and servlet -- then I'm leaning away from using 3rd party products.  I really don't know how these unknown/untested components will perform in production/load ??

I'm hoping someone here can answer my question definitively......

1) Yes -- this is how mod_rewrite/servlet can do what you want....
2) No -- for these reasons.... it's not possible -- but you could use this approach instead..... hopefully without having to resort to 3rd party products....

I'll consider your thoughts on 2) -- but hope someone here can address 1) for me.....

Talk Soon

Thanks very much
0
 
LVL 5

Accepted Solution

by:
mrielf earned 1000 total points
ID: 12384888
Sorry I'm not good at JSP programing, but here is the idea:

You must set these headers with response.setHeader:

Cache-Control: private
Pragma: public    
Content-type: application/x-download
Content-Disposition: attachment; filename="FileName"
Accept-Ranges: bytes
Content-Length: FileSize

I found this script (rewriten by me litle). You can rewrite it to your needs:



<?xml version="1.0"?>
<jsp:root xmlns:jsp="http://java.sun.com/JSP/Page" version="1.2">

<jsp:directive.page session="false" import="java.io.*" />
<jsp:scriptlet>
   String p = request.getQueryString();
   boolean ok = true;
   ok = p!=null;
   if (ok) {
      response.setHeader("Content-type","application/x-download");
      response.setHeader("Content-disposition",
         "attachment; filename="+p);
      try {
         int l = (int) new File(p).length();
         response.setContentLength(l);
         byte[] b = new byte[l];
         FileInputStream f = new FileInputStream(p);
         f.read(b);
         ServletOutputStream o = response.getOutputStream();
         o.write(b,0,l);
         o.flush();
         o.close();
         f.close();
      } catch (Exception e) {
         ok = false;
      }
   }
   if (!ok) {
      response.sendError(HttpServletResponse.SC_BAD_REQUEST);
   }
 </jsp:scriptlet>
</jsp:root>
0
 

Author Comment

by:fmisa
ID: 12400694

Not sure if this going to work - in a scalable manner ?

>> FileInputStream f = new FileInputStream(p);

"p" is the "filename"

But all I've got is the requested URL.....
Apache is already managing the alias mapping//translation to hard-drive for me;  I don't want to do this from my servlet ?

RootDrive:\
                HTTPSeverFolder\
                       htdocs\
                           downloads\
                               MyFile.pdf
                AppServerFolder\
                       App\
                            WEB-INF\
                                 classes\
                                            MyDownloadServlet.class

1) How is my servlet going to "map" URL http://host/download/MyFile.pdf   ==>  drive:\\HTTPServerFolder\htdocs\downloads\MyFile.pdf   ??
     I could have many diffent alias and download directories -- I don't want to manage this meta-data in servlet..... which is why I wanted apache to do the work of download.
     I guess I could use somekind of url/folder naming convention -- but this whole approach is starting to feel like a real hack ? Don't you think.

2) Can the servlet even see/access files outside the scope of it's "context" ..... WEB-INF ??
     I suspect - if I use absolute file path (not relative) - I should be able to open any file on the harddrive -- but then that brings me back to point 1) ??


Am I missing something ?

I had hoped that what I'm looking to do with mod_rewrite/AuthenticationServlet should be easy ??
Surely someone out there has done something similar without have to resort to creating a sort of mini-web/content server in their servlet ??

Any ideas out there ???
0
 
LVL 5

Expert Comment

by:mrielf
ID: 12408467
Alternative solution is that not to use rewrite module, instead set apache authentication with alternative authentication module...

Authentication with external CGI or PHP script
http://mod-auth-script.sourceforge.net/

External Authentication Module:
http://unixpapa.com/mod_auth_external.html

Apache authentication module using IBM DB2
http://mod-auth-ibmdb2.sourceforge.net/

0
 

Author Comment

by:fmisa
ID: 12477922
Thanks for your patience .....

I appreciate your help -- you've got me on the right track......

Please give me another day or two to evaluate -- it's almose working right......
I just want to make sure the code works right before I "accept"


Thanks


Frank
0
 

Author Comment

by:fmisa
ID: 12525585
Thanks  mrielf......

I really appreciate the help.......
I've accepted -- though I was worried about the overhead of having a servlet serve all the requested "static" content back instead of the HTTP server.
I've tested -- and the extra overhead does not seem to be a big deal ?

** Though I have accepted -- please comment -- one last time on the following........

Though Netscape is working fine -- MSIE is giving me very strange behaviour;  would you be kind enough to comment on the following behaviour:

Everything works fine in the MSIE scenario -- my JSP page is executed -- and when I "print out" values of parameters only the "fileName" is correct.
However, when I actually allow the following code to execute -- it seems the "fileName" is not being set correctly ??

>> response.setHeader("Content-type","application/x-download");
>> response.setHeader("content-disposition","attachment;filename=.....
>> //....etc.etc.
>> File aRequestedFile = ....
>> //.... base my code on your example etc.etc.
>> o.write(b,0,l);
>> o.close();
>> o.flush();

Whenever the requested URL is https://.....   i.e. a long paramter value associated with the key:  ?krypto=kZtbzjcqp.....etc.  
It seems the MSIE file download dialog pops-up -- prompting me to "SAVE"  or "OPEN"  
BUT -- the fileName is NOT the fileName I set in my response header ??
Instead -- it seems to include the a portion of the "krypto" parameter value ??

Any idea what might be confusing MSIE ??
Again -- Netscape seems to be working better.......

Hope to hear from you one last time......

Thanks for your help.....


Frank



0
 

Author Comment

by:fmisa
ID: 12525603
Also....

FYI

* My research into apache modules:
    a) mod_auth_any
    b) mod_auth_external
    suggests I'd most likely get into scenarios where users would have to authenticate twice.

* Servlet "Filters" I believe -- would give a better solution -- but don't think I can run "Filters" on my current version of WebSpherev.4.x  ??
See:
https://urlrewrite.dev.java.net/
http://publib.boulder.ibm.com/infocenter/wasinfo/index.jsp?topic=/com.ibm.wasee.doc/info/ee/ae/tsec_servlet.html

I'll look into "filters" more carefull later......


Cheers
0
 
LVL 5

Expert Comment

by:mrielf
ID: 12527605
Hi!

This is a php example for this problem (i found it on the net):

    $user_agent = strtolower ($_SERVER["HTTP_USER_AGENT"]);
    if ((is_integer (strpos($user_agent, "msie"))) && (is_integer (strpos($user_agent, "win"))))
    {
      header( "Content-Disposition: filename=".basename($filename).";" );
    } else {
      header( "Content-Disposition: attachment; filename=".basename($filename).";" );
    }

From this examle, it seems to me, if client is MSIE, then "attacment; " part must be excluded.

(Sorry for php source. As I said, I'm not expert at jsp programing. Also sorry for my bad english)
0

Featured Post

Looking for a new Web Host?

Lunarpages' assortment of hosting products and solutions ensure a perfect fit for anyone looking to get their vision or products to market. Our award winning customer support and 30-day money back guarantee show the pride we take in being the industry's premier MSP.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

When it comes to security, close monitoring is a must. According to WhiteHat Security annual report, a substantial number of all web applications are vulnerable always. Monitis offers a new product - fully-featured Website security monitoring and pr…
Without even knowing it, most of us are using web applications on a daily basis.  In fact, Gmail and Yahoo email, Twitter, Facebook, and eBay are used by most of us daily—and they are web applications. We generally confuse these web applications to…
Explain concepts important to validation of email addresses with regular expressions. Applies to most languages/tools that uses regular expressions. Consider email address RFCs: Look at HTML5 form input element (with type=email) regex pattern: T…
This Micro Tutorial will demonstrate how to add subdomains to your content reports. This can be very importing in having a site with multiple subdomains.
Suggested Courses

609 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question