Nicely done Dave.

I had thought the Acegi stuff for setting the secure urls would have been 
easier, but oh well.  That's always one of the drawbacks to using new 
frameworks, there is often a steep learning curve :/

-- Allen


On Tue, 2006-01-10 at 07:36, David M Johnson wrote:
> OK, Roller now does scheme enforcement via Acegi configured via  
> roller.properties. Since I'm new to Acegi, I've summarized the  
> changes below for your review.
> 
> - Dave
> 
> 
> ========== roller.properties
> 
> If you want to protect URLs by using HTTPS, you simply turn on scheme  
> enforcement in your roller.properties override file. You can use Ant- 
> style URL patterns to specify which URLs need HTTPS. For example,  
> this turns on HTTPS for the user profile and admin pages:
> 
>      # Enable scheme enforcement?
>      # Scheme enforcement ensures that specific URLs are viewed only  
> via HTTPS
>      schemeenforcement.enabled=true
>      # URL patterns that require HTTPS
>      schemeenforcement.https.urls=/editor/yourProfile.do*,/admin/ 
> user.do*
> 
> Like secure login, scheme enforcement defaults to false.
> 
> Note that I don't list the login pages as those are already  
> configured via the securelogin.enabled property.
> 
> 
> ========== RollerContext.java : initializeSecurityFeatures()
> 
> Inside Roller's context init, here's what we do to tell Acegi about  
> our protected URLs:
> 
>        if (RollerConfig.getBooleanProperty 
> ("schemeenforcement.enabled")) {
> 
>              ChannelProcessingFilter procfilter =
>                  (ChannelProcessingFilter)ctx.getBean 
> ("channelProcessingFilter");
>              ConfigAttributeDefinition secureDef = new  
> ConfigAttributeDefinition();
>              secureDef.addConfigAttribute(new SecurityConfig 
> ("REQUIRES_SECURE_CHANNEL"));
>              ConfigAttributeDefinition insecureDef = new  
> ConfigAttributeDefinition();
>              insecureDef.addConfigAttribute(new SecurityConfig 
> ("REQUIRES_INSECURE_CHANNEL"));
>              PathBasedFilterInvocationDefinitionMap defmap =
>                  (PathBasedFilterInvocationDefinitionMap) 
> procfilter.getFilterInvocationDefinitionSource();
> 
>              // add HTTPS URL path patterns to Acegi config
>              String httpsUrlsProp = RollerConfig.getProperty 
> ("schemeenforcement.https.urls");
>              if (httpsUrlsProp != null) {
>                  String[] httpsUrls = StringUtils.stripAll 
> (StringUtils.split(httpsUrlsProp, ",") );
>                  for (int i=0; i<httpsUrls.length; i++) {
>                      defmap.addSecureUrl(httpsUrls[i], secureDef);
>                  }
>              }
>              // all other action URLs are non-HTTPS
>              defmap.addSecureUrl("/**/*.do*", insecureDef);
>          }
> 
> It wasn't exactly easy to figure out how to do that, BTW.
> 
> 
> ========== Cleanup
> 
> We don't use these anymore so I deleted them:
> 
>      SslUtil.java
>      SecureTag.java
>      SchemeEnforcementFilter.java
>      securelogin.http.port property
>      securelogin.https.port property
>      securelogin.https.headername property
>      securelogin.https.headervalue property
> 
> 
> 
> 
> 
> 
> 
> 
> On Jan 9, 2006, at 12:26 PM, Matt Raible wrote:
> 
> > On 1/9/06, Allen Gilliland <[EMAIL PROTECTED]> wrote:
> >> Matt is the authority on Acegi, but I believe there is a way to  
> >> list the
> >> urls that Acegi should guarantee for SSL transport in the  
> >> security.xml.
> >> Then Acegi takes care of the protocol switching.  Right now I don't
> >> think some of our secure login property info is being mapped to the
> >> Acegi config, so we still need to do that.
> >
> > I believe I did handle this as part of the integration, but didn't
> > test it.  If it doesn't work, let me know and I'll fix it.
> >
> >>
> >> I definitely think that we shouldn't need the old "secure" tag  
> >> that we
> >> were using and I'm also not sure that we need to continue with old
> >> secureheader stuff.  I've moved the secureheader stuff outside of  
> >> Roller
> >> for blogs.sun.com and I think that's the proper place for it.
> >
> > Right, Acegi Security should be able to handle anything that the
> > "secure" tag did.  Also, I didn't account for the secureheader stuff,
> > so moving it outside Roller would be great. ;-)
> >
> >>
> >> -- Allen
> >>
> >>
> >> On Mon, 2006-01-09 at 07:47, Dave Johnson wrote:
> >>> Regarding:
> >>> http://opensource2.atlassian.com/projects/roller/browse/ROL-989
> >>>
> >>> The user profile page allows a user to change his/her password and
> >>> sends passwords in the clear, so I'd to make it more secure for  
> >>> sites
> >>> that require HTTPS for logins. The easiest way to do this seems  
> >>> to be
> >>> to force HTTPS on that page and that's what I've done in my local
> >>> workspace.
> >>>
> >>> Here's a summary of my changes (code is below): inside the
> >>> YourProfileAction.edit() method, I check to see if secure login is
> >>> enabled. If secure login is enabled but the current request is not
> >>> secure, I redirect to a secure version of the URL.
> >>>
> >>> I have two questions before I continue this work and add the same  
> >>> code
> >>> to user-admin:
> >>> 1) Is this the right way to do this, given that we're now using  
> >>> Acegi?
> >
> > You shouldn't need any code, just configure it in security.xml.
> > Unfortunately, I don't think there's a way to say "only require SSL if
> > secure login is enabled". ;-)
> >
> > ... so maybe you will need some code.
> >
> > Matt
> >
> >>> 2) Do we need the <roller:secure> tag on any of our pages  
> >>> anymore, now
> >>> that we're using Acegi?
> >>>
> >>> - Dave
> >>>
> >>>
> >>>
> >>> PS: here are the specific changes:
> >>>
> >>>
> >>> ==================== roller.properties
> >>>
> >>> Roller properties needs to change to allow the YourProfileAction to
> >>> run under HTTPS.
> >>>
> >>> schemeenforcement.https.urls=/j_security_check,/auth,/login- 
> >>> redirect.jsp,/login.jsp,/editor/yourProfile.do
> >>>
> >>>
> >>>
> >>> ==================== YourProfileAction.java
> >>>
> >>> The YourProfileAction.java method needs code to test for
> >>> securelogin.enabled and isSecure(). We can't use the <roller:secure>
> >>> tag on the JSP page because by the time we get there the response is
> >>> already committed.
> >>>
> >>>
> >>>          ActionForward forward =
> >>> mapping.findForward("yourProfile.page");
> >>>          try
> >>>          {
> >>> +            if
> >>> (RollerConfig.getBooleanProperty("securelogin.enabled") &&
> >>> !SslUtil.isSecure(request)) {
> >>> +                response.sendRedirect(SslUtil.getRedirectString(
> >>> +                    request,
> >>> request.getSession().getServletContext(), true));
> >>> +                return mapping.findForward("access-denied");
> >>> +            }
> >>>              RollerSession rollerSession =
> >>> RollerSession.getRollerSession(request);
> >>>              UserData ud = rollerSession.getAuthenticatedUser();
> >>>              UserFormEx form = (UserFormEx)actionForm;
> >>>
> >>>
> >>>
> >>> ==================== SslUtil.java
> >>>
> >>> We need a way to test isSecure() using the appropirate properties:
> >>>
> >>> +    /**
> >>> +     * Test for HTTPS connection by using request.isSecure() or,
> >>> +     * if httpsHeaderName is set, test for reqest header instead.
> >>> +     * If httpsHeaderValue is also set, test for that specific  
> >>> value.
> >>> +     */
> >>> +    public static boolean isSecure(HttpServletRequest request) {
> >>> +        String httpsHeaderName =
> >>> RollerConfig.getProperty("securelogin.https.headername");
> >>> +        String httpsHeaderValue =
> >>> RollerConfig.getProperty("securelogin.https.headervalue");
> >>> +        boolean secure = false;
> >>> +        if (httpsHeaderName == null) {
> >>> +            secure = request.isSecure();
> >>> +        } else {
> >>> +            String headerValue = request.getHeader 
> >>> (httpsHeaderName);
> >>> +            if (headerValue != null && headerValue.trim().length 
> >>> () >
> >>> 0) {
> >>> +                secure = httpsHeaderValue==null ||
> >>> httpsHeaderValue.equals(headerValue);
> >>> +            }
> >>> +        }
> >>> +        return secure;
> >>> +    }
> >>> +
> >>>
> >>
> >>
> 

Reply via email to