Thanks for the expanded explanation I will take a look at this technique today and see if it fits with what I am trying to do.

Keith

On Nov 3, 2008, at 8:20 PM, Jonathan Barker wrote:

Keith,

My rationale is that I only ever create / populate a UserState ASO if a user logs in. This is for a site where only the Login and PasswordResetRequest
pages can be accessed without being logged in to the application.

Since I will only ever create the ASO once a user is authenticated, I know that the authentication information I need is in the Acegi SecurityContext.


-So, a user logs in and the authentication information is stored in the
SecurityContext.
-The user is directed (in this case) to a dashboard-like summary page. This page injects the UserState ASO. When the page code accesses the ASO, the
actual creation of the ASO is triggered.
-By providing an explicit builder / creator method in the AppModule, I can initialize that object however I want. In my case, I store some basic user information, but I also build up a partial company hierarchy for the user,
and store that in the ASO.

With respect to SecurityContextHolder.getContext(), this is something that
Acegi provides and if you look at the code for the IfRole component in
tapestry5-acegi, you will see it used there. I feel a little accessing it
this way and not injecting it, but it's fast and easy.

The full method is:

        public void
contributeApplicationStateManager(MappedConfiguration<Class,
ApplicationStateContribution> configuration, final HierarchyService
hierarchyService, final UserProfileDAO profileDao)
          {
            ApplicationStateCreator<UserState> creator = new
ApplicationStateCreator<UserState>()
            {
              public UserState create()
              {
                  UserState state = new UserState();
                  SecurityContext context =
SecurityContextHolder.getContext();
                
                  Authentication authResult = context.getAuthentication();
                  if (authResult == null) throw new RuntimeException("no
auth when trying to create UserState");
                  Object principal = authResult.getPrincipal();
                                if (principal instanceof UserProfile){
                                        //logger.debug("Regular user logging
in: " + authResult.getName());
                                        // force this to have a current
session to avoid LAZY init exceptions
                                        UserProfile profile =
profileDao.findById(((UserProfile) principal).getId(), false);
        
state.setFullName(profile.getOwner().getFullName());
        
state .setFocusCompanies (hierarchyService.getFocusCompaniesForPerson(null,pro
file.getOwner()));
        
state .setPrimaryCompany (hierarchyService.getPrimaryCompany(state.getFocusCom
panies()));
                                        CompanyTreeNode root = new
CompanyTreeNode(null, state.getPrimaryCompany());
                                        Set<Company> dependentCompanies =
new HashSet<Company>();
        
state .setDependentHierarchy (hierarchyService.populateDependencies(dependentC
ompanies, root, state.getPrimaryCompany()));
        
state.setDependentCompanies(dependentCompanies);
                                } else {
                                        //logger.debug("Administrative user
loggin in: " + authResult.getName());
                                        state.setPrimaryCompany(null);
        
state.setFullName(authResult.getName());
                                        state.setDependentCompanies(new
HashSet<Company>());
                                }
                                state.setUsername(authResult.getName());
                                return state;
                }
            };
        
            configuration.add(UserState.class, new
ApplicationStateContribution("session", creator));
          }


-----Original Message-----
From: Keith Bottner [mailto:[EMAIL PROTECTED]
Sent: Monday, November 03, 2008 13:44
To: Tapestry users
Subject: Re: Accessing ApplicationStateManager from within a Filter

Jonathan,

You are correct. I am really attempting to retrieve the authentication
information from the Acegi security and set my @ApplicationState
fields that I use throughout my application. To do this I was going to
try to override the filter, retrieve the Acegi security information
and then set the appropriate application state objects using the
ApplicationStateManager.

I think I see what you are doing, but I am still unclear on exactly
how the code you provided integrates appropriately. Sorry to request a
larger explanation but I am still having a problem finding low level
information about how Tapestry ties things together.

Would you mind expanding on the explanation and potentially providing
the rest of the method for clarification?

Thanks in advance,

Keith

On Nov 3, 2008, at 11:11 AM, Jonathan Barker wrote:

Keith,

It sounds like you're trying to do something similar to what I was
trying to
do with Acegi.  Basically, I wanted to populate a UserState object
with
sensible information after a successful authentication.  I
contributed to
the Application State Manager, and pulled the info from Acegi,
rather than
the other way around.  I flipped the problem upside down.

Here's a piece of what I wrote:


        public void
contributeApplicationStateManager(MappedConfiguration<Class,
ApplicationStateContribution> configuration, final HierarchyService
hierarchyService, final UserProfileDAO profileDao)
          {
            ApplicationStateCreator<UserState> creator = new
ApplicationStateCreator<UserState>()
            {
              public UserState create()
              {
                  UserState state = new UserState();
                  SecurityContext context =
SecurityContextHolder.getContext();

                  Authentication authResult = context.getAuthentication();
                  if (authResult == null) throw new RuntimeException("no
auth when trying to create UserState");
                .... more lookups, and other stuff...

-----Original Message-----
From: Keith Bottner [mailto:[EMAIL PROTECTED]
Sent: Monday, November 03, 2008 11:48
To: Tapestry users
Subject: Re: Accessing ApplicationStateManager from within a Filter

This is the hardest part about grasping Tapestry 5, knowing what you can do and how you can do it when there seems to be an endless way to
tie things together that are loosely if at all documented. So I
apologize if the additional details to my original question lead to
one of these solutions that I am just unable to determine from the
context of the proposed solutions.

I tried to keep my question at simple as possible without revealing
too many details and getting bogged down in integration issues but I will outline a little more of what I am trying to do for the sake of
seeking clarity.

I am using Acegi-Security, as such I am overriding the
AuthenticationProcessingFilter that the Acegi-Security library sets
up
in its module. Now in my library module I construct my specific
version of AuthenticationProcessingFilter which is a subclass of
AuthenticationProcessingFilter and overrides the appropriate methods.
In those methods I am attempting to access the
ApplicationStateManager.

As I specified in the earlier email the ApplicationStateManager
always
comes in as null.

Here is the code from the Acegi-Security LibraryModule that is
relevant to the AuthenticationProcessingFilter.

   public static void contributeAlias(@AcegiServices
SaltSourceService saltSource,
           @AcegiServices AuthenticationProcessingFilter
authenticationProcessingFilter,
           Configuration<AliasContribution> configuration) {

configuration.add(AliasContribution.create(SaltSourceService.class,
saltSource));

configuration
.add(AliasContribution.create(AuthenticationProcessingFilter.class,
authenticationProcessingFilter));
   }

   public static void contributeHttpServletRequestHandler(
         OrderedConfiguration<HttpServletRequestFilter>
configuration,
         @InjectService("HttpSessionContextIntegrationFilter")
HttpServletRequestFilter httpSessionContextIntegrationFilter,
         @InjectService("AuthenticationProcessingFilter")
HttpServletRequestFilter authenticationProcessingFilter,
         @InjectService("RememberMeProcessingFilter")
HttpServletRequestFilter rememberMeProcessingFilter,
         @InjectService("SecurityContextHolderAwareRequestFilter")
HttpServletRequestFilter
         securityContextHolderAwareRequestFilter,
         @InjectService("AnonymousProcessingFilter")
HttpServletRequestFilter anonymousProcessingFilter) {

configuration.add("acegiHttpSessionContextIntegrationFilter",
httpSessionContextIntegrationFilter, "before:acegi*");
       configuration.add("acegiAuthenticationProcessingFilter",
authenticationProcessingFilter);
       configuration.add("acegiRememberMeProcessingFilter",
rememberMeProcessingFilter);

configuration.add("acegiSecurityContextHolderAwareRequestFilter",
securityContextHolderAwareRequestFilter,
               "after:acegiRememberMeProcessingFilter");
       configuration.add("acegiAnonymousProcessingFilter",
anonymousProcessingFilter,
               "after:acegiRememberMeProcessingFilter",
               "after:acegiAuthenticationProcessingFilter");
   }

   @Marker(AcegiServices.class)
   public static AuthenticationProcessingFilter
buildRealAuthenticationProcessingFilter(
       @AcegiServices final AuthenticationManager manager,
       @AcegiServices final RememberMeServices rememberMeServices,
       @Inject @Value("${acegi.check.url}") final String authUrl,
@Inject @Value("${acegi.target.url}") final String targetUrl,
       @Inject @Value("${acegi.failure.url}") final String
failureUrl)
   throws Exception {
       AuthenticationProcessingFilter filter = new
AuthenticationProcessingFilter();
       filter.setAuthenticationManager(manager);
       filter.setAuthenticationFailureUrl(failureUrl);
       filter.setDefaultTargetUrl(targetUrl);
       filter.setFilterProcessesUrl(authUrl);
       filter.setRememberMeServices(rememberMeServices);
       filter.afterPropertiesSet();
       return filter;
   }

   @Marker(AcegiServices.class)
   public static HttpServletRequestFilter
buildAuthenticationProcessingFilter(final
AuthenticationProcessingFilter filter)
   throws Exception {
       return new HttpServletRequestFilterWrapper(filter);
   }


NOW, in my LibraryModule I have the following methods that I believe should override the AuthenticationProcessingFilter appropriately but
still ends up resulting in a null for ApplicationStateManager.

 public static AuthenticationProcessingFilter
buildMyAuthenticationProcessingFilter(
                @AcegiServices final AuthenticationManager manager,
                @AcegiServices final RememberMeServices rememberMeServices,
                @InjectService ("ApplicationStateManager")
ApplicationStateManager asm,
                @Inject @Value( "${acegi.check.url}" ) final String authUrl,
                @Inject @Value( "${acegi.target.url}" ) final String
targetUrl,
                @Inject @Value( "${acegi.failure.url}" ) final String
failureUrl
                ) throws Exception
        {
                AuthenticationProcessingFilter filter = new
CustomAuthenticationProcessingFilter(asm);
                filter.setAuthenticationManager(manager);
                filter.setAuthenticationFailureUrl(failureUrl);
                filter.setDefaultTargetUrl(targetUrl);
                filter.setFilterProcessesUrl(authUrl);
                filter.setRememberMeServices(rememberMeServices);
                filter.afterPropertiesSet();
                return filter;
        }

 public static void
contributeAliasOverrides(@InjectService("MySaltSource")
SaltSourceService saltSource,
     @InjectService("MyAuthenticationProcessingFilter")
AuthenticationProcessingFilter authenticationProcessingFilter,
     Configuration<AliasContribution> configuration)
 {

configuration.add(AliasContribution.create(SaltSourceService.class,
saltSource));

configuration
.add(AliasContribution.create(AuthenticationProcessingFilter.class,
authenticationProcessingFilter));
 }

Now I am not typically the type to post this much detail as I know it
is difficult to help with such an issue, but the Tapestry 5
documentation is lacking in how everything gets weaved together and
what standard patterns are useful, IMHO. So if someone could please
help me to figure out how I can pass the AppliationStateManager
appropriately I would appreciate it.

BTW, I am using .15

Thanks in advance for any help,

Keith

On Nov 1, 2008, at 1:13 PM, Howard Lewis Ship wrote:

When you contribute a filter, you need to instantiate it. Generally
it looks something like:

public void
contributeRequestHandler(OrderedConfiguration<RequestFilter>
configuration, ObjectLocator locator)
{
 configuration.add("MyFilter", locator.autobuild(MyFilter.class));
}

The ObjectLocator is a resource of the RequestHandler service that
can
be injected into contribute methods for the RequestHandler service
and
allows access to other services within the IoC Registry; it also
handle instantiation of objects with injection for you. So MyFilter
doesn't have to be a service but can still be injected.
Contributing
an object instance to a filter does not do any injection, but
autobuild() does.

In the current .16 snapshot, you can use @Inject on fields of
MyFilter
in addition to injection through the constructor.  This was added
because people got confused:  in pages and components you use
@Inject
on fields, but in service implementation, 5.0.15 requires that
dependencies be passed through the constructor.  Again, 5.0.16
allows
you to code services and other objects more consistently (but with
the
runtime overhead of using reflection to update the private fields).

On Fri, Oct 31, 2008 at 2:41 PM, Keith Bottner <[EMAIL PROTECTED]>
wrote:
Is it possible to retrieve ApplicationStateManager from within a
Filter?

I tried using an @Inject and it always returns null.
I tried placing it in the constructor of the filter but when it is
accessed
it is null.

Is there a recommend way of doing this or is it even advisable?

Thanks in advance for your help.

Keith

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]





--
Howard M. Lewis Ship

Creator Apache Tapestry and Apache HiveMind

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]



---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]


---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]



---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]


---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]



---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to