You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@tapestry.apache.org by Ulrich Stärk <ul...@spielviel.de> on 2009/01/23 12:10:09 UTC

Re: Authentication

Hi Borut,

the problem was that both the OpenIdProcessingFilter and the filter used 
for form-based authentication both were configured for the same url, 
namely spring-security.check.url. Therefore both filters tried to 
process the credentials entered, which had to fail. I updated the wiki 
article. Basically it's all about introducing a new symbol, 
spring-security.openidcheck.url with the value 
"/j_spring_openid_security_check" and configuring the login page and the 
OpenId processing filter to use this instead of the 
spring-security.check.url. Then you can have to forms on your login 
page, one for openid login and the other for form-based logins and 
everything should work.

Cheers,

Uli


Borut Bolčina schrieb:
> Sure!
> 
> 2008/12/12 Ulrich Stärk <ul...@spielviel.de>
> 
>> Please give me some time to have a look, atm I'm busy writing a paper for a
>> conference in january.
>>
>> Cheers,
>>
>> Uli
>>
>> Borut Bolčina schrieb:
>>
>>  Hello Ulrich,
>>> I hope you don't mind me writing you directly. I am trying to implement
>>> OpenID and Username/Password authentication. I read your great article at
>>> T5
>>> wiki.
>>>
>>> My goal: authenticate via DaoAuthenticationProvider if user inputs
>>> username
>>> and password OR authenticate via OpenIDAuthenticationProvider if user
>>> enters
>>> openid url.
>>>
>>> The problem: OpenIDAuthenticationProvider is trying to authenticate
>>> eventhough it is contributed as second provider.
>>>
>>> Can you please have a look at the AppModule code and suggest a correction?
>>>
>>> AppModule.java
>>> ============
>>> import java.io.IOException;
>>>
>>> import
>>> nu.localhost.tapestry5.springsecurity.services.SpringSecurityServices;
>>> import
>>>
>>> nu.localhost.tapestry5.springsecurity.services.internal.HttpServletRequestFilterWrapper;
>>>
>>> import org.apache.tapestry5.SymbolConstants;
>>> import org.apache.tapestry5.ioc.MappedConfiguration;
>>> import org.apache.tapestry5.ioc.OrderedConfiguration;
>>> import org.apache.tapestry5.ioc.ServiceBinder;
>>> import org.apache.tapestry5.ioc.annotations.Inject;
>>> import org.apache.tapestry5.ioc.annotations.InjectService;
>>> import org.apache.tapestry5.ioc.annotations.Local;
>>> import org.apache.tapestry5.ioc.annotations.Value;
>>> import org.apache.tapestry5.services.HttpServletRequestFilter;
>>> import org.apache.tapestry5.services.Request;
>>> import org.apache.tapestry5.services.RequestFilter;
>>> import org.apache.tapestry5.services.RequestHandler;
>>> import org.apache.tapestry5.services.Response;
>>> import org.slf4j.Logger;
>>> import org.springframework.security.AuthenticationManager;
>>> import org.springframework.security.providers.AuthenticationProvider;
>>> import org.springframework.security.providers.dao.SaltSource;
>>> import org.springframework.security.providers.encoding.PasswordEncoder;
>>> import
>>>
>>> org.springframework.security.providers.openid.OpenIDAuthenticationProvider;
>>> import
>>>
>>> org.springframework.security.ui.openid.OpenIDAuthenticationProcessingFilter;
>>> import org.springframework.security.ui.rememberme.RememberMeServices;
>>> import org.springframework.security.userdetails.UserDetailsService;
>>>
>>> /**
>>>  * This module is automatically included as part of the Tapestry IoC
>>> Registry, it's a good place to configure and extend
>>>  * Tapestry, or to place your own service definitions.
>>>  */
>>> public class AppModule {
>>>    public static void bind(ServiceBinder binder) {
>>>        binder.bind(PersistenceManager.class,
>>> PersistenceManagerImpl.class);
>>>    }
>>>
>>>    public static void
>>> contributeApplicationDefaults(MappedConfiguration<String, String>
>>> configuration) {
>>>        configuration.add(SymbolConstants.SUPPORTED_LOCALES,
>>> "sl_SI,sr,en");
>>>
>>>        // The factory default is true but during the early stages of an
>>> application
>>>        // overriding to false is a good idea. In addition, this is often
>>> overridden
>>>        // on the command line as -Dtapestry.production-mode=false
>>>        configuration.add(SymbolConstants.PRODUCTION_MODE, "false");
>>>        configuration.add(SymbolConstants.COMPRESS_WHITESPACE, "false");
>>>
>>>        configuration.add("spring-security.failure.url", "/login/failed");
>>>        // configuration.add( "spring-security.accessDenied.url",
>>> "/forbidden" );
>>>        // configuration.add(
>>>        // "spring-security.check.url",
>>>        // "/j_spring_security_check" );
>>>        configuration.add("spring-security.target.url", "/index");
>>>        // configuration.add( "spring-security.afterlogout.url", "/" );
>>>        // configuration.add( "spring-security.rememberme.key",
>>> "REMEMBERMEKEY" );
>>>        configuration.add("spring-security.loginform.url", "/login");
>>>        // configuration.add( "spring-security.force.ssl.login", "false" );
>>>        // configuration.add( "spring-security.anonymous.key",
>>> "acegi_anonymous" );
>>>        // configuration.add(
>>>        // "spring-security.anonymous.attribute",
>>>        // "anonymous,ROLE_ANONYMOUS" );
>>>        configuration.add( "spring-security.password.salt", "DEADBEEF" );
>>>    }
>>>
>>>    /**
>>>     * This is a service definition, the service will be named
>>> "TimingFilter". The interface, RequestFilter, is used
>>>     * within the RequestHandler service pipeline, which is built from the
>>> RequestHandler service configuration.
>>>     * Tapestry IoC is responsible for passing in an appropriate Logger
>>> instance. Requests for static resources are
>>>     * handled at a higher level, so this filter will only be invoked for
>>> Tapestry related requests.
>>>     *
>>>     * <p>
>>>     * Service builder methods are useful when the implementation is inline
>>> as an inner class (as here) or require some
>>>     * other kind of special initialization. In most cases, use the static
>>> bind() method instead.
>>>     *
>>>     * <p>
>>>     * If this method was named "build", then the service id would be taken
>>> from the service interface and would be
>>>     * "RequestFilter". Since Tapestry already defines a service named
>>> "RequestFilter" we use an explicit service id
>>>     * that we can reference inside the contribution method.
>>>     */
>>>    public RequestFilter buildTimingFilter(final Logger log) {
>>>        return new RequestFilter() {
>>>            public boolean service(Request request, Response response,
>>> RequestHandler handler) throws IOException {
>>>                long startTime = System.currentTimeMillis();
>>>
>>>                try {
>>>                    // The responsibility of a filter is to invoke the
>>> corresponding method
>>>                    // in the handler. When you chain multiple filters
>>> together, each filter
>>>                    // received a handler that is a bridge to the next
>>> filter.
>>>
>>>                    return handler.service(request, response);
>>>                } finally {
>>>                    long elapsed = System.currentTimeMillis() - startTime;
>>>
>>>                    log.info(String.format("Request time: %d ms",
>>> elapsed));
>>>                }
>>>            }
>>>        };
>>>    }
>>>
>>>    /**
>>>     * This is a contribution to the RequestHandler service configuration.
>>> This is how we extend Tapestry using the
>>>     * timing filter. A common use for this kind of filter is transaction
>>> management or security. The @Local annotation
>>>     * selects the desired service by type, but only from the same module.
>>> Without @Local, there would be an error due
>>>     * to the other service(s) that implement RequestFilter (defined in
>>> other modules).
>>>     */
>>>    public void
>>> contributeRequestHandler(OrderedConfiguration<RequestFilter>
>>> configuration, @Local RequestFilter filter) {
>>>        // Each contribution to an ordered configuration has a name, When
>>> necessary, you may
>>>        // set constraints to precisely control the invocation order of the
>>> contributed filter
>>>        // within the pipeline.
>>>
>>>        configuration.add("Timing", filter);
>>>    }
>>>
>>>    /* COMMON UserDetailsService */
>>>    public static UserDetailsService buildUserDetailsService(@Inject
>>> PersistenceManager persistenceManager, final Logger log) {
>>>        return new UserDetailsServiceImpl(persistenceManager,log);
>>>    }
>>>
>>>    /* USERNAME, PASSWORD */
>>> //    public static UserDetailsService
>>> buildUserDetailsWithUsernameAndPasswordService(/*@Inject PasswordEncoder
>>> encoder,
>>> //            @Inject SaltSource salt, */final Logger log) {
>>> //        return new UserDetailsWithUsernameAndPasswordService(/*encoder,
>>> salt, */log);
>>> //    }
>>>
>>>    /* OPENID */
>>> //    public static UserDetailsService buildUserDetailsWithOpenIDService()
>>> {
>>> //        return new UserDetailsWithOpenIDServiceImpl();
>>> //    }
>>>
>>>    public static OpenIDAuthenticationProvider
>>> buildOpenIDAuthenticationProvider(
>>>            @InjectService("UserDetailsWithOpenIDService")
>>> UserDetailsService userDetailsService) throws Exception {
>>>        OpenIDAuthenticationProvider provider = new
>>> OpenIDAuthenticationProvider();
>>>
>>>        provider.setUserDetailsService(userDetailsService);
>>>        provider.afterPropertiesSet();
>>>
>>>        return provider;
>>>    }
>>>
>>>    public static void
>>> contributeProviderManager(OrderedConfiguration<AuthenticationProvider>
>>> configuration,
>>>
>>>            @InjectService("DaoAuthenticationProvider")
>>> AuthenticationProvider daoAuthenticationProvider,
>>>            @InjectService("OpenIDAuthenticationProvider")
>>> AuthenticationProvider openIdAuthenticationProvider) {
>>>
>>>        configuration.add("daoAuthenticationProvider",
>>> daoAuthenticationProvider);
>>>        configuration.add("openIDAuthenticationProvider",
>>> openIdAuthenticationProvider);
>>>    }
>>>
>>>
>>>    public static OpenIDAuthenticationProcessingFilter
>>> buildRealOpenIDAuthenticationProcessingFilter(
>>>            @SpringSecurityServices final AuthenticationManager manager,
>>>            @SpringSecurityServices final RememberMeServices
>>> rememberMeServices,
>>>            @Inject @Value("${spring-security.check.url}") final String
>>> authUrl,
>>>            @Inject @Value("${spring-security.target.url}") final String
>>> targetUrl,
>>>            @Inject @Value("${spring-security.failure.url}") final String
>>> failureUrl) throws Exception {
>>>        OpenIDAuthenticationProcessingFilter filter = new
>>> OpenIDAuthenticationProcessingFilter();
>>>
>>>        filter.setAuthenticationManager(manager);
>>>        filter.setAuthenticationFailureUrl(failureUrl);
>>>        filter.setDefaultTargetUrl(targetUrl);
>>>        filter.setFilterProcessesUrl(authUrl);
>>>        filter.setRememberMeServices(rememberMeServices);
>>>        filter.afterPropertiesSet();
>>>
>>>        return filter;
>>>    }
>>>
>>>    public static HttpServletRequestFilter
>>> buildOpenIDAuthenticationProcessingFilter(
>>>            final OpenIDAuthenticationProcessingFilter filter) {
>>>        return new HttpServletRequestFilterWrapper(filter);
>>>    }
>>>
>>>    public static void contributeHttpServletRequestHandler(
>>>            OrderedConfiguration<HttpServletRequestFilter> configuration,
>>>
>>>            @InjectService("OpenIDAuthenticationProcessingFilter")
>>> HttpServletRequestFilter openIDAuthenticationProcessingFilter) {
>>>        configuration.add("openIDAuthenticationProcessingFilter",
>>>
>>>        openIDAuthenticationProcessingFilter,
>>>
>>>        "before:springSecurityAuthenticationProcessingFilter",
>>>
>>>        "after:springSecurityHttpSessionContextIntegrationFilter");
>>>    }
>>>
>>> }
>>>
>>>
>>>
>>> Is there a problem in this last method
>>> ("before:springSecurityAuthenticationProcessingFilter")? Both forms (for
>>> u/p
>>> and openid url) are on the same page.
>>>
>>> <html xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
>>>    <head>
>>>        <title>Najdi.si prijavna stran</title>
>>>        <link rel="stylesheet" type="text/css"
>>> href="${asset:context:css/iopenid.css}" />
>>>    </head>
>>>    <body>
>>>        <t:layout xmlns:t="
>>> http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
>>>
>>>            <div style="margin-left: 50px">
>>>                <t:block t:id="loginWithUserNameAndPassword">
>>>                    <p>
>>>                        Prijavite se z uporabniškim imenom in geslom ali z
>>>                        <a t:type="actionlink" t:id="refreshOpenIDZone"
>>> href="#" t:zone="loginZone">OpenID</a>
>>>                    </p>
>>>                    <form xmlns:t="
>>> http://tapestry.apache.org/schema/tapestry_5_0_0.xsd"
>>> action="${loginCheckUrl}" method="POST">
>>>                        <t:if test="failed">
>>>                            Napačno uporabniško ime ali geslo!
>>>                            <br />
>>>                        </t:if>
>>>                        <label class="username"
>>> for="j_username">uporabniško
>>> ime:</label>
>>>                        <input class="username" name="j_username"
>>> type="text" size="10" maxlength="30" />
>>>                        <label class="password"
>>> for="j_password">geslo:</label>
>>>                        <input class="password" name="j_password"
>>> type="password" size="10" maxlength="30" />
>>>                        <input id="submit" class="submit" type="submit"
>>> value="log in" />
>>>                    </form>
>>>                    <p>Še nimate Najdi.si računa? <a t:type="pagelink"
>>> t:page="Register" href="#">Registrirajte se!</a></p>
>>>                    <p><a t:type="pagelink" t:page="RetrievePassword"
>>> href="#">Pozabil sem geslo.</a></p>
>>>                </t:block>
>>>                <t:block t:id="loginWithOpenID">
>>>                    <p>
>>>                        Prijavite se z
>>>                        <a t:type="actionlink"
>>> t:id="refreshUsernamePasswordZone" href="#"
>>> t:zone="loginZone">uporabniškim
>>> imenom in
>>>                            geslom</a>
>>>                        ali z OpenID
>>>                    </p>
>>>                    <form xmlns:t="
>>> http://tapestry.apache.org/schema/tapestry_5_0_0.xsd"
>>> action="${loginCheckUrl}" method="POST">
>>>                        <t:if test="failed">
>>>                            Napaka!
>>>                            <br />
>>>                        </t:if>
>>>                        <label class="username"
>>> for="j_username">OpenID:</label>
>>>                        <input class="username" name="j_username"
>>> type="text" size="30" />
>>>                        <input id="submit" class="submit" type="submit"
>>> value="log in" />
>>>                    </form>
>>>                    <p>Še nimate Najdi.si računa? Ob <a t:type="pagelink"
>>> t:page="Register" href="#">registraciji</a> dobite tudi Najdi.si
>>> OpenID.</p>
>>>                </t:block>
>>>                <t:zone t:id="loginZone">
>>>                    <t:delegate to="loginWithUserNameAndPassword" />
>>>                </t:zone>
>>>                <br />
>>>
>>>            </div>
>>>
>>>        </t:layout>
>>>    </body>
>>> </html>
>>>
>>>
>>> public class Login {
>>>    @Inject
>>>    @Property
>>>    private Block loginWithUserNameAndPassword;
>>>
>>>    @Inject
>>>    @Property
>>>    private Block loginWithOpenID;
>>>
>>>    @Inject
>>>    @Property
>>>    private Request _request;
>>>
>>>    void onActionFromRefreshPage() {
>>>        // Nothing to do - the page will get fresh times as it is rendered.
>>>    }
>>>
>>>    Block onActionFromRefreshOpenIDZone() {
>>>        // Check this is an AJAX link - if the link is clicked before the
>>> DOM is fully loaded then AJAX behaviour won't
>>>        // be there so don't try returning a Block. See
>>> https://issues.apache.org/jira/browse/TAP5-1 .
>>>        if (!_request.isXHR()) {
>>>            return null;
>>>        }
>>>
>>>        // Return the zone we want rendered. Without Ajax we'd typically
>>> return the page we want rendered.
>>>        return loginWithOpenID;
>>>    }
>>>
>>>    Block onActionFromRefreshUsernamePasswordZone() {
>>>        // Check this is an AJAX link - if the link is clicked before the
>>> DOM is fully loaded then AJAX behaviour won't
>>>        // be there so don't try returning a Block. See
>>> https://issues.apache.org/jira/browse/TAP5-1 .
>>>        if (!_request.isXHR()) {
>>>            return null;
>>>        }
>>>
>>>        // Return the zone we want rendered. Without Ajax we'd typically
>>> return the page we want rendered.
>>>        return loginWithUserNameAndPassword;
>>>    }
>>>
>>>    @Inject
>>>    @Value("${spring-security.check.url}")
>>>    private String checkUrl;
>>>
>>>    @Inject
>>>    private Request request;
>>>
>>>    private boolean failed = false;
>>>
>>>    public boolean isFailed() {
>>>        return failed;
>>>    }
>>>
>>>    public String getLoginCheckUrl() {
>>>        return request.getContextPath() + checkUrl;
>>>    }
>>>
>>>    void onActivate(String extra) {
>>>        if (extra.equals("failed")) {
>>>            failed = true;
>>>        }
>>>    }
>>>
>>> I would be really gratefull for your help!
>>>
>>> Regards,
>>> Borut
>>>
>>


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
For additional commands, e-mail: users-help@tapestry.apache.org


Re: Authentication

Posted by Borut Bolčina <bo...@gmail.com>.
Ups, that was beers :-)

2009/1/23 Borut Bolčina <bo...@gmail.com>

> 100 bears for Ulrich!
>
> It works. You made my day. Thanks,
>
> -Borut
>
> 2009/1/23 Ulrich Stärk <ul...@spielviel.de>
>
> Hi Borut,
>>
>> the problem was that both the OpenIdProcessingFilter and the filter used
>> for form-based authentication both were configured for the same url, namely
>> spring-security.check.url. Therefore both filters tried to process the
>> credentials entered, which had to fail. I updated the wiki article.
>> Basically it's all about introducing a new symbol,
>> spring-security.openidcheck.url with the value
>> "/j_spring_openid_security_check" and configuring the login page and the
>> OpenId processing filter to use this instead of the
>> spring-security.check.url. Then you can have to forms on your login page,
>> one for openid login and the other for form-based logins and everything
>> should work.
>>
>>
>> Cheers,
>>
>> Uli
>>
>>
>> Borut Bolčina schrieb:
>>
>>> Sure!
>>>
>>> 2008/12/12 Ulrich Stärk <ul...@spielviel.de>
>>>
>>>  Please give me some time to have a look, atm I'm busy writing a paper
>>>> for a
>>>> conference in january.
>>>>
>>>> Cheers,
>>>>
>>>> Uli
>>>>
>>>> Borut Bolčina schrieb:
>>>>
>>>>  Hello Ulrich,
>>>>
>>>>> I hope you don't mind me writing you directly. I am trying to implement
>>>>> OpenID and Username/Password authentication. I read your great article
>>>>> at
>>>>> T5
>>>>> wiki.
>>>>>
>>>>> My goal: authenticate via DaoAuthenticationProvider if user inputs
>>>>> username
>>>>> and password OR authenticate via OpenIDAuthenticationProvider if user
>>>>> enters
>>>>> openid url.
>>>>>
>>>>> The problem: OpenIDAuthenticationProvider is trying to authenticate
>>>>> eventhough it is contributed as second provider.
>>>>>
>>>>> Can you please have a look at the AppModule code and suggest a
>>>>> correction?
>>>>>
>>>>> AppModule.java
>>>>> ============
>>>>> import java.io.IOException;
>>>>>
>>>>> import
>>>>> nu.localhost.tapestry5.springsecurity.services.SpringSecurityServices;
>>>>> import
>>>>>
>>>>>
>>>>> nu.localhost.tapestry5.springsecurity.services.internal.HttpServletRequestFilterWrapper;
>>>>>
>>>>> import org.apache.tapestry5.SymbolConstants;
>>>>> import org.apache.tapestry5.ioc.MappedConfiguration;
>>>>> import org.apache.tapestry5.ioc.OrderedConfiguration;
>>>>> import org.apache.tapestry5.ioc.ServiceBinder;
>>>>> import org.apache.tapestry5.ioc.annotations.Inject;
>>>>> import org.apache.tapestry5.ioc.annotations.InjectService;
>>>>> import org.apache.tapestry5.ioc.annotations.Local;
>>>>> import org.apache.tapestry5.ioc.annotations.Value;
>>>>> import org.apache.tapestry5.services.HttpServletRequestFilter;
>>>>> import org.apache.tapestry5.services.Request;
>>>>> import org.apache.tapestry5.services.RequestFilter;
>>>>> import org.apache.tapestry5.services.RequestHandler;
>>>>> import org.apache.tapestry5.services.Response;
>>>>> import org.slf4j.Logger;
>>>>> import org.springframework.security.AuthenticationManager;
>>>>> import org.springframework.security.providers.AuthenticationProvider;
>>>>> import org.springframework.security.providers.dao.SaltSource;
>>>>> import org.springframework.security.providers.encoding.PasswordEncoder;
>>>>> import
>>>>>
>>>>>
>>>>> org.springframework.security.providers.openid.OpenIDAuthenticationProvider;
>>>>> import
>>>>>
>>>>>
>>>>> org.springframework.security.ui.openid.OpenIDAuthenticationProcessingFilter;
>>>>> import org.springframework.security.ui.rememberme.RememberMeServices;
>>>>> import org.springframework.security.userdetails.UserDetailsService;
>>>>>
>>>>> /**
>>>>>  * This module is automatically included as part of the Tapestry IoC
>>>>> Registry, it's a good place to configure and extend
>>>>>  * Tapestry, or to place your own service definitions.
>>>>>  */
>>>>> public class AppModule {
>>>>>   public static void bind(ServiceBinder binder) {
>>>>>       binder.bind(PersistenceManager.class,
>>>>> PersistenceManagerImpl.class);
>>>>>   }
>>>>>
>>>>>   public static void
>>>>> contributeApplicationDefaults(MappedConfiguration<String, String>
>>>>> configuration) {
>>>>>       configuration.add(SymbolConstants.SUPPORTED_LOCALES,
>>>>> "sl_SI,sr,en");
>>>>>
>>>>>       // The factory default is true but during the early stages of an
>>>>> application
>>>>>       // overriding to false is a good idea. In addition, this is often
>>>>> overridden
>>>>>       // on the command line as -Dtapestry.production-mode=false
>>>>>       configuration.add(SymbolConstants.PRODUCTION_MODE, "false");
>>>>>       configuration.add(SymbolConstants.COMPRESS_WHITESPACE, "false");
>>>>>
>>>>>       configuration.add("spring-security.failure.url",
>>>>> "/login/failed");
>>>>>       // configuration.add( "spring-security.accessDenied.url",
>>>>> "/forbidden" );
>>>>>       // configuration.add(
>>>>>       // "spring-security.check.url",
>>>>>       // "/j_spring_security_check" );
>>>>>       configuration.add("spring-security.target.url", "/index");
>>>>>       // configuration.add( "spring-security.afterlogout.url", "/" );
>>>>>       // configuration.add( "spring-security.rememberme.key",
>>>>> "REMEMBERMEKEY" );
>>>>>       configuration.add("spring-security.loginform.url", "/login");
>>>>>       // configuration.add( "spring-security.force.ssl.login", "false"
>>>>> );
>>>>>       // configuration.add( "spring-security.anonymous.key",
>>>>> "acegi_anonymous" );
>>>>>       // configuration.add(
>>>>>       // "spring-security.anonymous.attribute",
>>>>>       // "anonymous,ROLE_ANONYMOUS" );
>>>>>       configuration.add( "spring-security.password.salt", "DEADBEEF" );
>>>>>   }
>>>>>
>>>>>   /**
>>>>>    * This is a service definition, the service will be named
>>>>> "TimingFilter". The interface, RequestFilter, is used
>>>>>    * within the RequestHandler service pipeline, which is built from
>>>>> the
>>>>> RequestHandler service configuration.
>>>>>    * Tapestry IoC is responsible for passing in an appropriate Logger
>>>>> instance. Requests for static resources are
>>>>>    * handled at a higher level, so this filter will only be invoked for
>>>>> Tapestry related requests.
>>>>>    *
>>>>>    * <p>
>>>>>    * Service builder methods are useful when the implementation is
>>>>> inline
>>>>> as an inner class (as here) or require some
>>>>>    * other kind of special initialization. In most cases, use the
>>>>> static
>>>>> bind() method instead.
>>>>>    *
>>>>>    * <p>
>>>>>    * If this method was named "build", then the service id would be
>>>>> taken
>>>>> from the service interface and would be
>>>>>    * "RequestFilter". Since Tapestry already defines a service named
>>>>> "RequestFilter" we use an explicit service id
>>>>>    * that we can reference inside the contribution method.
>>>>>    */
>>>>>   public RequestFilter buildTimingFilter(final Logger log) {
>>>>>       return new RequestFilter() {
>>>>>           public boolean service(Request request, Response response,
>>>>> RequestHandler handler) throws IOException {
>>>>>               long startTime = System.currentTimeMillis();
>>>>>
>>>>>               try {
>>>>>                   // The responsibility of a filter is to invoke the
>>>>> corresponding method
>>>>>                   // in the handler. When you chain multiple filters
>>>>> together, each filter
>>>>>                   // received a handler that is a bridge to the next
>>>>> filter.
>>>>>
>>>>>                   return handler.service(request, response);
>>>>>               } finally {
>>>>>                   long elapsed = System.currentTimeMillis() -
>>>>> startTime;
>>>>>
>>>>>                   log.info(String.format("Request time: %d ms",
>>>>> elapsed));
>>>>>               }
>>>>>           }
>>>>>       };
>>>>>   }
>>>>>
>>>>>   /**
>>>>>    * This is a contribution to the RequestHandler service
>>>>> configuration.
>>>>> This is how we extend Tapestry using the
>>>>>    * timing filter. A common use for this kind of filter is transaction
>>>>> management or security. The @Local annotation
>>>>>    * selects the desired service by type, but only from the same
>>>>> module.
>>>>> Without @Local, there would be an error due
>>>>>    * to the other service(s) that implement RequestFilter (defined in
>>>>> other modules).
>>>>>    */
>>>>>   public void
>>>>> contributeRequestHandler(OrderedConfiguration<RequestFilter>
>>>>> configuration, @Local RequestFilter filter) {
>>>>>       // Each contribution to an ordered configuration has a name, When
>>>>> necessary, you may
>>>>>       // set constraints to precisely control the invocation order of
>>>>> the
>>>>> contributed filter
>>>>>       // within the pipeline.
>>>>>
>>>>>       configuration.add("Timing", filter);
>>>>>   }
>>>>>
>>>>>   /* COMMON UserDetailsService */
>>>>>   public static UserDetailsService buildUserDetailsService(@Inject
>>>>> PersistenceManager persistenceManager, final Logger log) {
>>>>>       return new UserDetailsServiceImpl(persistenceManager,log);
>>>>>   }
>>>>>
>>>>>   /* USERNAME, PASSWORD */
>>>>> //    public static UserDetailsService
>>>>> buildUserDetailsWithUsernameAndPasswordService(/*@Inject
>>>>> PasswordEncoder
>>>>> encoder,
>>>>> //            @Inject SaltSource salt, */final Logger log) {
>>>>> //        return new
>>>>> UserDetailsWithUsernameAndPasswordService(/*encoder,
>>>>> salt, */log);
>>>>> //    }
>>>>>
>>>>>   /* OPENID */
>>>>> //    public static UserDetailsService
>>>>> buildUserDetailsWithOpenIDService()
>>>>> {
>>>>> //        return new UserDetailsWithOpenIDServiceImpl();
>>>>> //    }
>>>>>
>>>>>   public static OpenIDAuthenticationProvider
>>>>> buildOpenIDAuthenticationProvider(
>>>>>           @InjectService("UserDetailsWithOpenIDService")
>>>>> UserDetailsService userDetailsService) throws Exception {
>>>>>       OpenIDAuthenticationProvider provider = new
>>>>> OpenIDAuthenticationProvider();
>>>>>
>>>>>       provider.setUserDetailsService(userDetailsService);
>>>>>       provider.afterPropertiesSet();
>>>>>
>>>>>       return provider;
>>>>>   }
>>>>>
>>>>>   public static void
>>>>> contributeProviderManager(OrderedConfiguration<AuthenticationProvider>
>>>>> configuration,
>>>>>
>>>>>           @InjectService("DaoAuthenticationProvider")
>>>>> AuthenticationProvider daoAuthenticationProvider,
>>>>>           @InjectService("OpenIDAuthenticationProvider")
>>>>> AuthenticationProvider openIdAuthenticationProvider) {
>>>>>
>>>>>       configuration.add("daoAuthenticationProvider",
>>>>> daoAuthenticationProvider);
>>>>>       configuration.add("openIDAuthenticationProvider",
>>>>> openIdAuthenticationProvider);
>>>>>   }
>>>>>
>>>>>
>>>>>   public static OpenIDAuthenticationProcessingFilter
>>>>> buildRealOpenIDAuthenticationProcessingFilter(
>>>>>           @SpringSecurityServices final AuthenticationManager manager,
>>>>>           @SpringSecurityServices final RememberMeServices
>>>>> rememberMeServices,
>>>>>           @Inject @Value("${spring-security.check.url}") final String
>>>>> authUrl,
>>>>>           @Inject @Value("${spring-security.target.url}") final String
>>>>> targetUrl,
>>>>>           @Inject @Value("${spring-security.failure.url}") final String
>>>>> failureUrl) throws Exception {
>>>>>       OpenIDAuthenticationProcessingFilter filter = new
>>>>> OpenIDAuthenticationProcessingFilter();
>>>>>
>>>>>       filter.setAuthenticationManager(manager);
>>>>>       filter.setAuthenticationFailureUrl(failureUrl);
>>>>>       filter.setDefaultTargetUrl(targetUrl);
>>>>>       filter.setFilterProcessesUrl(authUrl);
>>>>>       filter.setRememberMeServices(rememberMeServices);
>>>>>       filter.afterPropertiesSet();
>>>>>
>>>>>       return filter;
>>>>>   }
>>>>>
>>>>>   public static HttpServletRequestFilter
>>>>> buildOpenIDAuthenticationProcessingFilter(
>>>>>           final OpenIDAuthenticationProcessingFilter filter) {
>>>>>       return new HttpServletRequestFilterWrapper(filter);
>>>>>   }
>>>>>
>>>>>   public static void contributeHttpServletRequestHandler(
>>>>>           OrderedConfiguration<HttpServletRequestFilter> configuration,
>>>>>
>>>>>           @InjectService("OpenIDAuthenticationProcessingFilter")
>>>>> HttpServletRequestFilter openIDAuthenticationProcessingFilter) {
>>>>>       configuration.add("openIDAuthenticationProcessingFilter",
>>>>>
>>>>>       openIDAuthenticationProcessingFilter,
>>>>>
>>>>>       "before:springSecurityAuthenticationProcessingFilter",
>>>>>
>>>>>       "after:springSecurityHttpSessionContextIntegrationFilter");
>>>>>   }
>>>>>
>>>>> }
>>>>>
>>>>>
>>>>>
>>>>> Is there a problem in this last method
>>>>> ("before:springSecurityAuthenticationProcessingFilter")? Both forms
>>>>> (for
>>>>> u/p
>>>>> and openid url) are on the same page.
>>>>>
>>>>> <html xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
>>>>>   <head>
>>>>>       <title>Najdi.si prijavna stran</title>
>>>>>       <link rel="stylesheet" type="text/css"
>>>>> href="${asset:context:css/iopenid.css}" />
>>>>>   </head>
>>>>>   <body>
>>>>>       <t:layout xmlns:t="
>>>>> http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
>>>>>
>>>>>           <div style="margin-left: 50px">
>>>>>               <t:block t:id="loginWithUserNameAndPassword">
>>>>>                   <p>
>>>>>                       Prijavite se z uporabniškim imenom in geslom ali
>>>>> z
>>>>>                       <a t:type="actionlink" t:id="refreshOpenIDZone"
>>>>> href="#" t:zone="loginZone">OpenID</a>
>>>>>                   </p>
>>>>>                   <form xmlns:t="
>>>>> http://tapestry.apache.org/schema/tapestry_5_0_0.xsd"
>>>>> action="${loginCheckUrl}" method="POST">
>>>>>                       <t:if test="failed">
>>>>>                           Napačno uporabniško ime ali geslo!
>>>>>                           <br />
>>>>>                       </t:if>
>>>>>                       <label class="username"
>>>>> for="j_username">uporabniško
>>>>> ime:</label>
>>>>>                       <input class="username" name="j_username"
>>>>> type="text" size="10" maxlength="30" />
>>>>>                       <label class="password"
>>>>> for="j_password">geslo:</label>
>>>>>                       <input class="password" name="j_password"
>>>>> type="password" size="10" maxlength="30" />
>>>>>                       <input id="submit" class="submit" type="submit"
>>>>> value="log in" />
>>>>>                   </form>
>>>>>                   <p>Še nimate Najdi.si računa? <a t:type="pagelink"
>>>>> t:page="Register" href="#">Registrirajte se!</a></p>
>>>>>                   <p><a t:type="pagelink" t:page="RetrievePassword"
>>>>> href="#">Pozabil sem geslo.</a></p>
>>>>>               </t:block>
>>>>>               <t:block t:id="loginWithOpenID">
>>>>>                   <p>
>>>>>                       Prijavite se z
>>>>>                       <a t:type="actionlink"
>>>>> t:id="refreshUsernamePasswordZone" href="#"
>>>>> t:zone="loginZone">uporabniškim
>>>>> imenom in
>>>>>                           geslom</a>
>>>>>                       ali z OpenID
>>>>>                   </p>
>>>>>                   <form xmlns:t="
>>>>> http://tapestry.apache.org/schema/tapestry_5_0_0.xsd"
>>>>> action="${loginCheckUrl}" method="POST">
>>>>>                       <t:if test="failed">
>>>>>                           Napaka!
>>>>>                           <br />
>>>>>                       </t:if>
>>>>>                       <label class="username"
>>>>> for="j_username">OpenID:</label>
>>>>>                       <input class="username" name="j_username"
>>>>> type="text" size="30" />
>>>>>                       <input id="submit" class="submit" type="submit"
>>>>> value="log in" />
>>>>>                   </form>
>>>>>                   <p>Še nimate Najdi.si računa? Ob <a t:type="pagelink"
>>>>> t:page="Register" href="#">registraciji</a> dobite tudi Najdi.si
>>>>> OpenID.</p>
>>>>>               </t:block>
>>>>>               <t:zone t:id="loginZone">
>>>>>                   <t:delegate to="loginWithUserNameAndPassword" />
>>>>>               </t:zone>
>>>>>               <br />
>>>>>
>>>>>           </div>
>>>>>
>>>>>       </t:layout>
>>>>>   </body>
>>>>> </html>
>>>>>
>>>>>
>>>>> public class Login {
>>>>>   @Inject
>>>>>   @Property
>>>>>   private Block loginWithUserNameAndPassword;
>>>>>
>>>>>   @Inject
>>>>>   @Property
>>>>>   private Block loginWithOpenID;
>>>>>
>>>>>   @Inject
>>>>>   @Property
>>>>>   private Request _request;
>>>>>
>>>>>   void onActionFromRefreshPage() {
>>>>>       // Nothing to do - the page will get fresh times as it is
>>>>> rendered.
>>>>>   }
>>>>>
>>>>>   Block onActionFromRefreshOpenIDZone() {
>>>>>       // Check this is an AJAX link - if the link is clicked before the
>>>>> DOM is fully loaded then AJAX behaviour won't
>>>>>       // be there so don't try returning a Block. See
>>>>> https://issues.apache.org/jira/browse/TAP5-1 .
>>>>>       if (!_request.isXHR()) {
>>>>>           return null;
>>>>>       }
>>>>>
>>>>>       // Return the zone we want rendered. Without Ajax we'd typically
>>>>> return the page we want rendered.
>>>>>       return loginWithOpenID;
>>>>>   }
>>>>>
>>>>>   Block onActionFromRefreshUsernamePasswordZone() {
>>>>>       // Check this is an AJAX link - if the link is clicked before the
>>>>> DOM is fully loaded then AJAX behaviour won't
>>>>>       // be there so don't try returning a Block. See
>>>>> https://issues.apache.org/jira/browse/TAP5-1 .
>>>>>       if (!_request.isXHR()) {
>>>>>           return null;
>>>>>       }
>>>>>
>>>>>       // Return the zone we want rendered. Without Ajax we'd typically
>>>>> return the page we want rendered.
>>>>>       return loginWithUserNameAndPassword;
>>>>>   }
>>>>>
>>>>>   @Inject
>>>>>   @Value("${spring-security.check.url}")
>>>>>   private String checkUrl;
>>>>>
>>>>>   @Inject
>>>>>   private Request request;
>>>>>
>>>>>   private boolean failed = false;
>>>>>
>>>>>   public boolean isFailed() {
>>>>>       return failed;
>>>>>   }
>>>>>
>>>>>   public String getLoginCheckUrl() {
>>>>>       return request.getContextPath() + checkUrl;
>>>>>   }
>>>>>
>>>>>   void onActivate(String extra) {
>>>>>       if (extra.equals("failed")) {
>>>>>           failed = true;
>>>>>       }
>>>>>   }
>>>>>
>>>>> I would be really gratefull for your help!
>>>>>
>>>>> Regards,
>>>>> Borut
>>>>>
>>>>>
>>>>
>>
>

Re: Authentication

Posted by Borut Bolčina <bo...@gmail.com>.
100 bears for Ulrich!

It works. You made my day. Thanks,

-Borut

2009/1/23 Ulrich Stärk <ul...@spielviel.de>

> Hi Borut,
>
> the problem was that both the OpenIdProcessingFilter and the filter used
> for form-based authentication both were configured for the same url, namely
> spring-security.check.url. Therefore both filters tried to process the
> credentials entered, which had to fail. I updated the wiki article.
> Basically it's all about introducing a new symbol,
> spring-security.openidcheck.url with the value
> "/j_spring_openid_security_check" and configuring the login page and the
> OpenId processing filter to use this instead of the
> spring-security.check.url. Then you can have to forms on your login page,
> one for openid login and the other for form-based logins and everything
> should work.
>
>
> Cheers,
>
> Uli
>
>
> Borut Bolčina schrieb:
>
>> Sure!
>>
>> 2008/12/12 Ulrich Stärk <ul...@spielviel.de>
>>
>>  Please give me some time to have a look, atm I'm busy writing a paper for
>>> a
>>> conference in january.
>>>
>>> Cheers,
>>>
>>> Uli
>>>
>>> Borut Bolčina schrieb:
>>>
>>>  Hello Ulrich,
>>>
>>>> I hope you don't mind me writing you directly. I am trying to implement
>>>> OpenID and Username/Password authentication. I read your great article
>>>> at
>>>> T5
>>>> wiki.
>>>>
>>>> My goal: authenticate via DaoAuthenticationProvider if user inputs
>>>> username
>>>> and password OR authenticate via OpenIDAuthenticationProvider if user
>>>> enters
>>>> openid url.
>>>>
>>>> The problem: OpenIDAuthenticationProvider is trying to authenticate
>>>> eventhough it is contributed as second provider.
>>>>
>>>> Can you please have a look at the AppModule code and suggest a
>>>> correction?
>>>>
>>>> AppModule.java
>>>> ============
>>>> import java.io.IOException;
>>>>
>>>> import
>>>> nu.localhost.tapestry5.springsecurity.services.SpringSecurityServices;
>>>> import
>>>>
>>>>
>>>> nu.localhost.tapestry5.springsecurity.services.internal.HttpServletRequestFilterWrapper;
>>>>
>>>> import org.apache.tapestry5.SymbolConstants;
>>>> import org.apache.tapestry5.ioc.MappedConfiguration;
>>>> import org.apache.tapestry5.ioc.OrderedConfiguration;
>>>> import org.apache.tapestry5.ioc.ServiceBinder;
>>>> import org.apache.tapestry5.ioc.annotations.Inject;
>>>> import org.apache.tapestry5.ioc.annotations.InjectService;
>>>> import org.apache.tapestry5.ioc.annotations.Local;
>>>> import org.apache.tapestry5.ioc.annotations.Value;
>>>> import org.apache.tapestry5.services.HttpServletRequestFilter;
>>>> import org.apache.tapestry5.services.Request;
>>>> import org.apache.tapestry5.services.RequestFilter;
>>>> import org.apache.tapestry5.services.RequestHandler;
>>>> import org.apache.tapestry5.services.Response;
>>>> import org.slf4j.Logger;
>>>> import org.springframework.security.AuthenticationManager;
>>>> import org.springframework.security.providers.AuthenticationProvider;
>>>> import org.springframework.security.providers.dao.SaltSource;
>>>> import org.springframework.security.providers.encoding.PasswordEncoder;
>>>> import
>>>>
>>>>
>>>> org.springframework.security.providers.openid.OpenIDAuthenticationProvider;
>>>> import
>>>>
>>>>
>>>> org.springframework.security.ui.openid.OpenIDAuthenticationProcessingFilter;
>>>> import org.springframework.security.ui.rememberme.RememberMeServices;
>>>> import org.springframework.security.userdetails.UserDetailsService;
>>>>
>>>> /**
>>>>  * This module is automatically included as part of the Tapestry IoC
>>>> Registry, it's a good place to configure and extend
>>>>  * Tapestry, or to place your own service definitions.
>>>>  */
>>>> public class AppModule {
>>>>   public static void bind(ServiceBinder binder) {
>>>>       binder.bind(PersistenceManager.class,
>>>> PersistenceManagerImpl.class);
>>>>   }
>>>>
>>>>   public static void
>>>> contributeApplicationDefaults(MappedConfiguration<String, String>
>>>> configuration) {
>>>>       configuration.add(SymbolConstants.SUPPORTED_LOCALES,
>>>> "sl_SI,sr,en");
>>>>
>>>>       // The factory default is true but during the early stages of an
>>>> application
>>>>       // overriding to false is a good idea. In addition, this is often
>>>> overridden
>>>>       // on the command line as -Dtapestry.production-mode=false
>>>>       configuration.add(SymbolConstants.PRODUCTION_MODE, "false");
>>>>       configuration.add(SymbolConstants.COMPRESS_WHITESPACE, "false");
>>>>
>>>>       configuration.add("spring-security.failure.url", "/login/failed");
>>>>       // configuration.add( "spring-security.accessDenied.url",
>>>> "/forbidden" );
>>>>       // configuration.add(
>>>>       // "spring-security.check.url",
>>>>       // "/j_spring_security_check" );
>>>>       configuration.add("spring-security.target.url", "/index");
>>>>       // configuration.add( "spring-security.afterlogout.url", "/" );
>>>>       // configuration.add( "spring-security.rememberme.key",
>>>> "REMEMBERMEKEY" );
>>>>       configuration.add("spring-security.loginform.url", "/login");
>>>>       // configuration.add( "spring-security.force.ssl.login", "false"
>>>> );
>>>>       // configuration.add( "spring-security.anonymous.key",
>>>> "acegi_anonymous" );
>>>>       // configuration.add(
>>>>       // "spring-security.anonymous.attribute",
>>>>       // "anonymous,ROLE_ANONYMOUS" );
>>>>       configuration.add( "spring-security.password.salt", "DEADBEEF" );
>>>>   }
>>>>
>>>>   /**
>>>>    * This is a service definition, the service will be named
>>>> "TimingFilter". The interface, RequestFilter, is used
>>>>    * within the RequestHandler service pipeline, which is built from the
>>>> RequestHandler service configuration.
>>>>    * Tapestry IoC is responsible for passing in an appropriate Logger
>>>> instance. Requests for static resources are
>>>>    * handled at a higher level, so this filter will only be invoked for
>>>> Tapestry related requests.
>>>>    *
>>>>    * <p>
>>>>    * Service builder methods are useful when the implementation is
>>>> inline
>>>> as an inner class (as here) or require some
>>>>    * other kind of special initialization. In most cases, use the static
>>>> bind() method instead.
>>>>    *
>>>>    * <p>
>>>>    * If this method was named "build", then the service id would be
>>>> taken
>>>> from the service interface and would be
>>>>    * "RequestFilter". Since Tapestry already defines a service named
>>>> "RequestFilter" we use an explicit service id
>>>>    * that we can reference inside the contribution method.
>>>>    */
>>>>   public RequestFilter buildTimingFilter(final Logger log) {
>>>>       return new RequestFilter() {
>>>>           public boolean service(Request request, Response response,
>>>> RequestHandler handler) throws IOException {
>>>>               long startTime = System.currentTimeMillis();
>>>>
>>>>               try {
>>>>                   // The responsibility of a filter is to invoke the
>>>> corresponding method
>>>>                   // in the handler. When you chain multiple filters
>>>> together, each filter
>>>>                   // received a handler that is a bridge to the next
>>>> filter.
>>>>
>>>>                   return handler.service(request, response);
>>>>               } finally {
>>>>                   long elapsed = System.currentTimeMillis() - startTime;
>>>>
>>>>                   log.info(String.format("Request time: %d ms",
>>>> elapsed));
>>>>               }
>>>>           }
>>>>       };
>>>>   }
>>>>
>>>>   /**
>>>>    * This is a contribution to the RequestHandler service configuration.
>>>> This is how we extend Tapestry using the
>>>>    * timing filter. A common use for this kind of filter is transaction
>>>> management or security. The @Local annotation
>>>>    * selects the desired service by type, but only from the same module.
>>>> Without @Local, there would be an error due
>>>>    * to the other service(s) that implement RequestFilter (defined in
>>>> other modules).
>>>>    */
>>>>   public void
>>>> contributeRequestHandler(OrderedConfiguration<RequestFilter>
>>>> configuration, @Local RequestFilter filter) {
>>>>       // Each contribution to an ordered configuration has a name, When
>>>> necessary, you may
>>>>       // set constraints to precisely control the invocation order of
>>>> the
>>>> contributed filter
>>>>       // within the pipeline.
>>>>
>>>>       configuration.add("Timing", filter);
>>>>   }
>>>>
>>>>   /* COMMON UserDetailsService */
>>>>   public static UserDetailsService buildUserDetailsService(@Inject
>>>> PersistenceManager persistenceManager, final Logger log) {
>>>>       return new UserDetailsServiceImpl(persistenceManager,log);
>>>>   }
>>>>
>>>>   /* USERNAME, PASSWORD */
>>>> //    public static UserDetailsService
>>>> buildUserDetailsWithUsernameAndPasswordService(/*@Inject PasswordEncoder
>>>> encoder,
>>>> //            @Inject SaltSource salt, */final Logger log) {
>>>> //        return new
>>>> UserDetailsWithUsernameAndPasswordService(/*encoder,
>>>> salt, */log);
>>>> //    }
>>>>
>>>>   /* OPENID */
>>>> //    public static UserDetailsService
>>>> buildUserDetailsWithOpenIDService()
>>>> {
>>>> //        return new UserDetailsWithOpenIDServiceImpl();
>>>> //    }
>>>>
>>>>   public static OpenIDAuthenticationProvider
>>>> buildOpenIDAuthenticationProvider(
>>>>           @InjectService("UserDetailsWithOpenIDService")
>>>> UserDetailsService userDetailsService) throws Exception {
>>>>       OpenIDAuthenticationProvider provider = new
>>>> OpenIDAuthenticationProvider();
>>>>
>>>>       provider.setUserDetailsService(userDetailsService);
>>>>       provider.afterPropertiesSet();
>>>>
>>>>       return provider;
>>>>   }
>>>>
>>>>   public static void
>>>> contributeProviderManager(OrderedConfiguration<AuthenticationProvider>
>>>> configuration,
>>>>
>>>>           @InjectService("DaoAuthenticationProvider")
>>>> AuthenticationProvider daoAuthenticationProvider,
>>>>           @InjectService("OpenIDAuthenticationProvider")
>>>> AuthenticationProvider openIdAuthenticationProvider) {
>>>>
>>>>       configuration.add("daoAuthenticationProvider",
>>>> daoAuthenticationProvider);
>>>>       configuration.add("openIDAuthenticationProvider",
>>>> openIdAuthenticationProvider);
>>>>   }
>>>>
>>>>
>>>>   public static OpenIDAuthenticationProcessingFilter
>>>> buildRealOpenIDAuthenticationProcessingFilter(
>>>>           @SpringSecurityServices final AuthenticationManager manager,
>>>>           @SpringSecurityServices final RememberMeServices
>>>> rememberMeServices,
>>>>           @Inject @Value("${spring-security.check.url}") final String
>>>> authUrl,
>>>>           @Inject @Value("${spring-security.target.url}") final String
>>>> targetUrl,
>>>>           @Inject @Value("${spring-security.failure.url}") final String
>>>> failureUrl) throws Exception {
>>>>       OpenIDAuthenticationProcessingFilter filter = new
>>>> OpenIDAuthenticationProcessingFilter();
>>>>
>>>>       filter.setAuthenticationManager(manager);
>>>>       filter.setAuthenticationFailureUrl(failureUrl);
>>>>       filter.setDefaultTargetUrl(targetUrl);
>>>>       filter.setFilterProcessesUrl(authUrl);
>>>>       filter.setRememberMeServices(rememberMeServices);
>>>>       filter.afterPropertiesSet();
>>>>
>>>>       return filter;
>>>>   }
>>>>
>>>>   public static HttpServletRequestFilter
>>>> buildOpenIDAuthenticationProcessingFilter(
>>>>           final OpenIDAuthenticationProcessingFilter filter) {
>>>>       return new HttpServletRequestFilterWrapper(filter);
>>>>   }
>>>>
>>>>   public static void contributeHttpServletRequestHandler(
>>>>           OrderedConfiguration<HttpServletRequestFilter> configuration,
>>>>
>>>>           @InjectService("OpenIDAuthenticationProcessingFilter")
>>>> HttpServletRequestFilter openIDAuthenticationProcessingFilter) {
>>>>       configuration.add("openIDAuthenticationProcessingFilter",
>>>>
>>>>       openIDAuthenticationProcessingFilter,
>>>>
>>>>       "before:springSecurityAuthenticationProcessingFilter",
>>>>
>>>>       "after:springSecurityHttpSessionContextIntegrationFilter");
>>>>   }
>>>>
>>>> }
>>>>
>>>>
>>>>
>>>> Is there a problem in this last method
>>>> ("before:springSecurityAuthenticationProcessingFilter")? Both forms (for
>>>> u/p
>>>> and openid url) are on the same page.
>>>>
>>>> <html xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
>>>>   <head>
>>>>       <title>Najdi.si prijavna stran</title>
>>>>       <link rel="stylesheet" type="text/css"
>>>> href="${asset:context:css/iopenid.css}" />
>>>>   </head>
>>>>   <body>
>>>>       <t:layout xmlns:t="
>>>> http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
>>>>
>>>>           <div style="margin-left: 50px">
>>>>               <t:block t:id="loginWithUserNameAndPassword">
>>>>                   <p>
>>>>                       Prijavite se z uporabniškim imenom in geslom ali z
>>>>                       <a t:type="actionlink" t:id="refreshOpenIDZone"
>>>> href="#" t:zone="loginZone">OpenID</a>
>>>>                   </p>
>>>>                   <form xmlns:t="
>>>> http://tapestry.apache.org/schema/tapestry_5_0_0.xsd"
>>>> action="${loginCheckUrl}" method="POST">
>>>>                       <t:if test="failed">
>>>>                           Napačno uporabniško ime ali geslo!
>>>>                           <br />
>>>>                       </t:if>
>>>>                       <label class="username"
>>>> for="j_username">uporabniško
>>>> ime:</label>
>>>>                       <input class="username" name="j_username"
>>>> type="text" size="10" maxlength="30" />
>>>>                       <label class="password"
>>>> for="j_password">geslo:</label>
>>>>                       <input class="password" name="j_password"
>>>> type="password" size="10" maxlength="30" />
>>>>                       <input id="submit" class="submit" type="submit"
>>>> value="log in" />
>>>>                   </form>
>>>>                   <p>Še nimate Najdi.si računa? <a t:type="pagelink"
>>>> t:page="Register" href="#">Registrirajte se!</a></p>
>>>>                   <p><a t:type="pagelink" t:page="RetrievePassword"
>>>> href="#">Pozabil sem geslo.</a></p>
>>>>               </t:block>
>>>>               <t:block t:id="loginWithOpenID">
>>>>                   <p>
>>>>                       Prijavite se z
>>>>                       <a t:type="actionlink"
>>>> t:id="refreshUsernamePasswordZone" href="#"
>>>> t:zone="loginZone">uporabniškim
>>>> imenom in
>>>>                           geslom</a>
>>>>                       ali z OpenID
>>>>                   </p>
>>>>                   <form xmlns:t="
>>>> http://tapestry.apache.org/schema/tapestry_5_0_0.xsd"
>>>> action="${loginCheckUrl}" method="POST">
>>>>                       <t:if test="failed">
>>>>                           Napaka!
>>>>                           <br />
>>>>                       </t:if>
>>>>                       <label class="username"
>>>> for="j_username">OpenID:</label>
>>>>                       <input class="username" name="j_username"
>>>> type="text" size="30" />
>>>>                       <input id="submit" class="submit" type="submit"
>>>> value="log in" />
>>>>                   </form>
>>>>                   <p>Še nimate Najdi.si računa? Ob <a t:type="pagelink"
>>>> t:page="Register" href="#">registraciji</a> dobite tudi Najdi.si
>>>> OpenID.</p>
>>>>               </t:block>
>>>>               <t:zone t:id="loginZone">
>>>>                   <t:delegate to="loginWithUserNameAndPassword" />
>>>>               </t:zone>
>>>>               <br />
>>>>
>>>>           </div>
>>>>
>>>>       </t:layout>
>>>>   </body>
>>>> </html>
>>>>
>>>>
>>>> public class Login {
>>>>   @Inject
>>>>   @Property
>>>>   private Block loginWithUserNameAndPassword;
>>>>
>>>>   @Inject
>>>>   @Property
>>>>   private Block loginWithOpenID;
>>>>
>>>>   @Inject
>>>>   @Property
>>>>   private Request _request;
>>>>
>>>>   void onActionFromRefreshPage() {
>>>>       // Nothing to do - the page will get fresh times as it is
>>>> rendered.
>>>>   }
>>>>
>>>>   Block onActionFromRefreshOpenIDZone() {
>>>>       // Check this is an AJAX link - if the link is clicked before the
>>>> DOM is fully loaded then AJAX behaviour won't
>>>>       // be there so don't try returning a Block. See
>>>> https://issues.apache.org/jira/browse/TAP5-1 .
>>>>       if (!_request.isXHR()) {
>>>>           return null;
>>>>       }
>>>>
>>>>       // Return the zone we want rendered. Without Ajax we'd typically
>>>> return the page we want rendered.
>>>>       return loginWithOpenID;
>>>>   }
>>>>
>>>>   Block onActionFromRefreshUsernamePasswordZone() {
>>>>       // Check this is an AJAX link - if the link is clicked before the
>>>> DOM is fully loaded then AJAX behaviour won't
>>>>       // be there so don't try returning a Block. See
>>>> https://issues.apache.org/jira/browse/TAP5-1 .
>>>>       if (!_request.isXHR()) {
>>>>           return null;
>>>>       }
>>>>
>>>>       // Return the zone we want rendered. Without Ajax we'd typically
>>>> return the page we want rendered.
>>>>       return loginWithUserNameAndPassword;
>>>>   }
>>>>
>>>>   @Inject
>>>>   @Value("${spring-security.check.url}")
>>>>   private String checkUrl;
>>>>
>>>>   @Inject
>>>>   private Request request;
>>>>
>>>>   private boolean failed = false;
>>>>
>>>>   public boolean isFailed() {
>>>>       return failed;
>>>>   }
>>>>
>>>>   public String getLoginCheckUrl() {
>>>>       return request.getContextPath() + checkUrl;
>>>>   }
>>>>
>>>>   void onActivate(String extra) {
>>>>       if (extra.equals("failed")) {
>>>>           failed = true;
>>>>       }
>>>>   }
>>>>
>>>> I would be really gratefull for your help!
>>>>
>>>> Regards,
>>>> Borut
>>>>
>>>>
>>>
>