2

my application currently has one authentication defined for a specific URL, with a custom filter, where user is authenticated by extracting the user details from the URL (in the query string). This is working fine. Now I want to add a new authentication using an identity certificate for a different URL pattern (the authentication is completely different from the first one, it has a differnt user details service etc). I saw there's already support for x509 cert authentication in spring security. I want to understand what is the best configuration I should do considering the following:

  1. I want users access the different URL patterns to be authenticated by the relevant authentication, and not try first with one authentication and if that fails then try the other one. This is why I think I may need 2 different authentication managers?
  2. My application must be in HTTPS for all URLs
  3. I need to configure tomcat in a way where client authentication is required only for the specific URL pattern, not to all the application.

Here is what I have so far for the first authentication, any help would be appreciated:

security-applicationContext.xml:

<sec:http pattern="/urlAuth1" auto-config="false" entry-point-ref="url1EntryPoint">
    <sec:intercept-url pattern="/**" access="IS_AUTHENTICATED_FULLY" requires-channel="https" />
    <sec:custom-filter position="PRE_AUTH_FILTER" ref="urlPreAuthFilter"/>
</sec:http>
<bean id="urlPreAuthFilter" class="com.myapp.security.UrlPreAuthenticatedFilter">
    <property name="authenticationManager" ref="authenticationManager" />
</bean>
<bean id="urlPreAuthProvider" class="org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationProvider">
    <property name="preAuthenticatedUserDetailsService" ref="urlUserDetailsService" />
</bean>

<sec:authentication-manager alias="authenticationManager">
    <sec:authentication-provider ref="urlPreAuthProvider" />
</sec:authentication-manager>

Thanks!

EDIT - 30.01.13:

I added the following section to my security context.xml. When I debug my app when accessing both URLs patterns, I see that for first URL pattern (/urlAuth1) the getProviders() in the authenticationManager returns just one provider which is the urlPreAuthProvider, and for the second URL pattern (/certAuthTest) it returns two providers - the anonymous and preauthenticatedprovider which I guess are registered by default. For me this is OK since it means each pattern goes through the correct providers. I want to make sure I am not missing anything, does it seem right to you?

<sec:http pattern="/certAuthTest" auto-config="false">
    <sec:intercept-url pattern="/**" access="IS_AUTHENTICATED_FULLY" requires-channel="https" />
    <sec:x509 subject-principal-regex="CN=(.*?)," user-service-ref="certUserDetailsService"/>
</sec:http>

regarding the web.xml configuration for clientAuth, I'll do some more reading and see if this works. Thanks!

michalv82
  • 1,949
  • 4
  • 16
  • 17
  • 1
    You might be able to solve the problem by adding another authentication provider (not the authentication manager). For more details, please see http://stackoverflow.com/questions/4783063/configuring-spring-security-3-x-to-have-multiple-entry-points. – Ritesh Jan 29 '13 at 15:54
  • possible duplicate of [Mapping each http block to a specific Authentication Provider](http://stackoverflow.com/questions/5807863/mapping-each-http-block-to-a-specific-authentication-provider) – Raedwald Jan 07 '15 at 11:53

1 Answers1

3

You can declare separate authentication manager beans for each URL pattern you want and then assign them to the individual filter chains using the authentication-manager-ref attribute on the <http /> element.

<http pattern="/someapi/**"  authentication-manager-ref="someapiAuthMgr">
    ...
</http>

You can use the standard ProviderManager bean for the individual authentication managers.

To enforce HTTPS for all requests, you can use standard web.xml settings.

Client certificate authentication takes place when the SSL connection is established. So you either have it or you don't. Investigate the clientAuth tomcat connector setting. You can set it to "want" to ask for a client certificate but not require one for the SSL connection to succeed.

Community
  • 1
  • 1
Shaun the Sheep
  • 22,353
  • 1
  • 72
  • 100
  • Thanks for your answers. I added an update to my original question if you can take a look. – michalv82 Jan 30 '13 at 08:58
  • As part of it's bean bookkeeping, the `` element registers an internal authentication manager which delegates to a "parent" one (the external one which you define). So that's where the authentication providers you see are coming from. – Shaun the Sheep Jan 30 '13 at 13:03
  • but then how come that for the first http authentication, only one provider is found (urlPreAuthProvider which I defined in the xml), and for the other http authentication I have different providers which I didn't define anywhere? – michalv82 Jan 30 '13 at 16:06
  • This is straying off the original question, but you can look at the source if you really want to understand the gory details of how the namespace works. You can check out [`ProviderManager`](https://github.com/SpringSource/spring-security/blob/master/core/src/main/java/org/springframework/security/authentication/ProviderManager.java) to see how the authentication manager only invokes its "parent" if required. That may be what you're seeing. – Shaun the Sheep Jan 30 '13 at 16:50