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]

Reply via email to