Thank you for responding, and I can use your advice to make my code a
little less verbose and concise.  Alas, it did not address my core
issue of forcing authentication.  The behavior is exactly the same.

If I go to a protected resource with a Role requirement, then
authentication and an authorization check is performed.  But
otherwise, nothing, and I need the authentication done because that is
what defines the roles, and I have some pages that are accessible, but
adjust due to a user's restrictions (fine-grained access control)...

Perhaps it would help to elaborate on my solution...

My authentication mechanism is really done by a special SSO Filter.
The Filter populates the HTTPRequest's remote user, so then Lift can
simply ask that for who was authenticated.  While the Servlet layer
has a valid username, I still need to build some kind of bridge to
Lift land.  As a result, I have a specialized HttpAuthentication like
so:

case class FilterAuthentication (authorizationFunc:
PartialFunction[(String), Boolean]) extends HttpAuthentication {

  /** Extract the remote username from the HTTP Request. */
  private def authenticatedUsername (r : Req) =
r.request.asInstanceOf[HTTPRequestServlet].req.getRemoteUser().toLowerCase()

  /** Extract the Authenticated User and call the Authorization
function. */
  def verified_? = {
    case req => {
      authenticatedUsername(req) match {
        case u if null != u && u.length > 1 &&
authorizationFunc.isDefinedAt(u) => authorizationFunc(u)
        case _ => false
      }
    }
  }
}

Then, I need to hook this into LiftRules like so:

    LiftRules.authentication = FilterAuthentication( {
      case username => Log.info("Authenticating: " + username)
        val isAuthorized = Auth.isAuthorized(username)
        if (isAuthorized) {
          val authorizedRoles = Auth.authorizedRoles(username)
          userRoles(authorizedRoles)
        }
        isAuthorized
    })

Note that the Filter will acquire an authenticated user -- but that
user may still not have access to this particular application.  As a
result, I need to do the "isAuthorized" check that basically does a
lookup to see if jdoe, for example, is authorized to access my
application.  If he is, then roles are populated and true is returned;
if not, false is returned.

I need to restrict some pages, so I do something like:

    LiftRules.httpAuthProtectedResource.prepend {
      case Req("restricted" :: _,_,_) => restrictedRole
      case _ => Empty
    }

If the user goes to /restricted/, then I see the authentication and
authorization kick in.  But I am also interested in authentication
(i.e. validating that the user is allowed to access the application)
even if index.xhtml is hit.  I thought I am telling Lift to do that
with the "case _ => Empty".

I am not using the siteMap to generate my menus because I need to
control the styling.  As a result, when I create my menus, I do
something like:

<lift:Auth.secure role="restricted"><a href="/restricted/">Restricted
Access</a></lift:Auth.secure>

In my case, I actually have the privilege, so I should see this link,
however because Lift isn't calling the FilterAuthentication logic, it
doesn't know my roles and hence hides the link.
If I go to /restricted/, then all is well...

In summary, according to the documentation, returning an Empty should
force an authentication, but that doesn't seem to be working.  Am I
doing something wrong?  Or is the documentation incorrect?  Or is
there a bug in 2.0-M1?

(This is a big show stopper for me, so I certainly appreciate the
assistance.)

-- 
You received this message because you are subscribed to the Google Groups 
"Lift" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/liftweb?hl=en.

Reply via email to