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.