I would like to give users choice between a few (indirect) authentication options, similar to what stackoverflow and many other website offer. There would be a form login as well as OIDC options. I can do this by setting different endpoints protected by different indirect clients just like in jee-pac4j-demo
, however I'm not sure how I can make handling of the original requested URL work.
Here's my configuration:
<!-- form authentication -->
<filter>
<filter-name>FormFilter</filter-name>
<filter-class>org.pac4j.jee.filter.SecurityFilter</filter-class>
<init-param>
<param-name>configFactory</param-name>
<param-value>com.mycompany.authentication.Pac4jConfigFactory</param-value>
</init-param>
<init-param>
<param-name>clients</param-name>
<param-value>FormClient</param-value>
</init-param>
<init-param>
<param-name>authorizers</param-name>
<param-value>isAuthenticated</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>FormFilter</filter-name>
<url-pattern>/formLogin</url-pattern>
<url-pattern>/private-url</url-pattern>
<dispatcher>REQUEST</dispatcher>
</filter-mapping>
<!-- google oidc authentication -->
<filter>
<filter-name>GoogleOidcFilter</filter-name>
<filter-class>org.pac4j.jee.filter.SecurityFilter</filter-class>
<init-param>
<param-name>configFactory</param-name>
<param-value>com.mycompany.authentication.Pac4jConfigFactory</param-value>
</init-param>
<init-param>
<param-name>clients</param-name>
<param-value>GoogleOidcClient</param-value>
</init-param>
<init-param>
<param-name>authorizers</param-name>
<param-value>isAuthenticated</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>GoogleOidcFilter</filter-name>
<url-pattern>/googleOidcLogin</url-pattern>
<dispatcher>REQUEST</dispatcher>
</filter-mapping>
If the user calls a protected url (/private-url), he would be redirected to my FormClient login page where I have the username/password fields as well as a link to /googleOidcLogin.
If the user logs in with username/password everything is fine and the initial request is served after authentication. However, if the user clicks on the googleOidcLogin button, now that page is considered the initial request and it is the one restored after the authentication.
How can this be implemented with pac4j?
Ok, I found a way to implement this.
Since we're always going to
FormClient
before we can choose any of the the otherIndirectClient
s, all we need to do is instruct the otherIndirectClient
s not to save the initial request, and therefore not overwriting the one recorded byFormClient
. This way, when the otherIndirectClient
will restore the initial url it will restore the one saved byFormClient
.For that we need a custom implementation of
SavedRequestHandler
that only stores original url for the FormClient.the
FormClientOnlySavedRequestHandler
:And you register it in your
ConfigFactory
: