Announcement Announcement Module
No announcement yet.
Need help w. mod_jk2 acegi secured channel redirect Page Title Module
Move Remove Collapse
This topic is closed
Conversation Detail Module
  • Filter
  • Time
  • Show
Clear All
new posts

  • Need help w. mod_jk2 acegi secured channel redirect

    Hi all,

    We are using Acegi 0.8 in our webapp on Tomcat 5.0.28, and fronting it with Apache 2 mod_jk2 on Linux.

    I can get http://localhost/myapp and https://localhost/myapp to work properly when not using channelProcessingFilter.

    Now I am experimenting with using Acegi channelProcessingFilter to secure our login, registration and changepasword pages, and I am having difficulty. Using suggested config in Acegi's ref doc and default tomcat config of 8080/8443, I can get it to work (i.e. switch from http to https and back) when I browse to http://localhost:8080/myapps i.e. talking to tomcat directly, but when I try doing thru Apache/mod_jk2, my browser just hangs and eventually timed out.

    Here are my apache2 vhost settings:

    <VirtualHost *:443>
    <Location "/">
    JkUriSet worker ajp13:localhost:8009

    Here are my tomcat server.xml settings:

    <Connector port="8009" enableLookups="false" debug="0" protocol="AJP/1.3" />

    note: I tried various redirect port settings from none to 443, 8009, 8443 but no luck.

    Here are my acegi context xml:

    <bean id="secureChannelProcessor" class="net.sf.acegisecurity.securechannel.SecureCh annelProcessor">
    <property name="entryPoint">
    <ref local="retryWithHttpsEntryPoint"/>

    <bean id="retryWithHttpsEntryPoint" class="net.sf.acegisecurity.securechannel.RetryWit hHttpsEntryPoint">
    <property name="portMapper">
    <ref local="portMapper"/>

    <bean id="portMapper" class="net.sf.acegisecurity.util.PortMapperImpl">
    <property name="portMappings">
    <entry key="80"><value>443</value></entry>
    <entry key="8080"><value>443</value></entry>
    <entry key="8009"><value>443</value></entry>

    note: I tried the default settings as suggested in Acegi's doc but that didn't work thru mod_jk2, so I started experimenting with explicitly setting portmapping. I tried setting the value to 443, 8009 , 8009 but still no luck.

    Any help would be greatly accepted. Thanks.

  • #2
    Sorry, I haven't used channel security in combination with mod_jk2.

    The problem is perhaps due to SecureChannelProcessor and InsecureChannelProcessor both internally using invocation.getHttpRequest().isSecure() to decide whether the channel is secure or not. I'd expect Apache <--> Tomcat communications are always over HTTP. Thus, the infinte loop you see is probably due to an attempt to redirect to a secure channel, the browser establishing a secure channel to Apache, it then passing the request through - using HTTP not HTTPS - to Tomcat, and the process repeating.

    My suggestion would be to customise these two classes to use some mod_jk2 friendly manner of identifying if the Apache-handled request was over HTTP or HTTPS. Maybe some other people have suggestions on which HttpServletRequest parameter will reveal the port the Apache-handled request was received on.


    • #3
      Actually for mod_jk(2) apache <-> tomcat is typically over AJP connection. I can't remember it off the top of my head, but there are configuration settings so that Tomcat knows the connection is using HTTPS, try looking them up in the mod_jk documentation. I would recommend writing a simple JSP to test the isSecure() method until your configuration is passing this in correctly...


      • #4
        I'm not entirely sure if this is helpful - please ignore if not . . .

        I'm using Apache 2.0.53, Tomcat 5.0.30 (as supplied with jboss 3.2.7) and mod_jk (not jk2, though I was for a while, and I don't think it made any difference).

        I don't use Acegi (on my to-learn list, when I have time . . .), I have my own interceptor that checks for https or not, and does a redirect if necessary.
        request.isSecure() works fine for me. So however isSecure works, it gets the right answer, even though apache is handling the ssl stuff.
        And request.getRequestURL() comes through with http or https, as it came from the client.


        • #5
          Solution found

          Hi all,

          After struggling with this for weeks, we have finally found a solution. I am posting this in the hope that it could help others with similar issues.

          Disclaimer: I arrived at the working solution thru trial and error - but I can't honestly say I understand what is going on :-)

          * Firstly, don't use mod_jk2, it is now deprecated, use mod_jk 1.2.x instead.
          I have verified that my solution works with mod_jk1.2.x but not mod_jk2

          * In tomcat server.xml, configure 2 connectors, like so:

          <!-- Define a Coyote/JK2 AJP 1.3 Connector on
          port 8009 for http and 8449 for https

          <Connector port="8009"
          protocol="AJP/1.3" />

          <Connector port="8449"
          protocol="AJP/1.3" />

          * configure mod_jk with 2 workers, one for http the other https e.g.







          * In Apache, configure 2 name based virtual host, one for port 80, the other port 443. e.g.

          <VirtualHost *:80>
          ServerAdmin [email protected]
          JkMount / ajp13
          JkMount /* ajp13
          JkMount /admin ajp13
          JkMount /admin/* ajp13
          JkMount /manager ajp13
          JkMount /manager/* ajp13
          JkMount /jkstatus jkstatus
          JkMount /jkstatus/* jkstatus

          <VirtualHost *:443>
          ServerAdmin [email protected]
          JkMount / ajp13ssl
          JkMount /* ajp13ssl
          JkMount /admin ajp13ssl
          JkMount /admin/* ajp13ssl
          JkMount /manager ajp13ssl
          JkMount /manager/* ajp13ssl
          JkMount /jkstatus jkstatusssl
          JkMount /jkstatus/* jkstatus

          * Unfortunately, you are not quite done. Using mod_jk1.2.spring 1.1.5 and Acegi 0.8.2 there are some perculiar behaviors that force us to change our code. Basically when the automatic HTTP/HTTPS redirect is triggered by Acegi channelProcessingFilter, the redirect has to be a full URL, not a relative URL or spring MVC view name (which works if you are using Coyote but not when fronting tomcat with mod_jk using AJP). So whenever there is any redirection going on, e.g. login page, login failure, make sure you use spring's redirect view with a full URL. For example, I configure my acegi authenticationProcessingFilter like so:

          <bean id="authenticationProcessingFilter"
          class="net.sf.acegisecurity.ui.webapp.Authenticati onProcessingFilter">
          <property name="authenticationManager">
          <ref bean="authenticationManager"/>
          <property name="authenticationFailureUrl">
          <property name="defaultTargetUrl"><value>${your.serverpath}/</value></property>
          <property name="filterProcessesUrl"><value>/j_acegi_security_check</value></property>

          In our case, ${your.serverpath} is a JVM env var defined with:

          java ... -Dyour.serverpath= ...

          but may be there are other ways of passing that info to Acegi...

          Conclusion? The above seems to work for us, but I think there are some work that needs to be done in mod_jk and/or Acegi to address the last issue of needing absolute URL for redirection to work.


          • #6

            I've always found SSL/Redirect handling and apache/tomcat setup is a real pain. However, Acegi shouldn't need to know what the absolute server URL is, as this should be sorted out in the Tomcat and Apache configurations. I've always used mod_proxy rather than mod_jk as it's easier to work out what's going on and the connectors have often been buggy in the past.

            You can set the proxy server name and port on tomcat. These control what will be returned from request.getServerName() and request.getServerPort() so redirects should work OK. The "scheme" an also be used to set a connector to be "https". In the past I think I've used two non-ssl connectors in tomcat. One on port 8443 would have

            proxyPort="443" scheme="https" secure="true"

            for proxied ssl connections, and one on port 8080 with proxyPort=80. Both should have proxyName="<your host name>".

            Tomcat has no way of knowing internally that the first one isn't actually using SSL beyond apache. If Acegi does a redirect, it should end up back at this "fake" SSL listener and Acegi will think the connection is now secure.

            I think you should be able to use these parameters even if you're not using mod_proxy. I don't know what hocus-pocus mod_jk performs in this respect though. Must try it sometime .



            • #7
              Added a JIRA task to improve connector integration: