Discussion:
Multiple login forms and authentication providers
jnunderwood
2010-09-24 15:49:09 UTC
Permalink
Hello,

We are creating our first Grails app. We are enjoying it, but we have had to
learn a lot in a short period of time. I am in charge of the security
aspects of the project.

Our project has a particular authentication requirement. Most users will use
a login form which uses LDAP for authentication. However, some users do not
have LDAP accounts; they will need to use a different login form which will
use a database for authentication.

How should I approach this problem? I have figured out how to authenticate
with either the database OR with LDAP. But I don't know how to provide users
the option of choosing which authentication mechanism to use.

Any suggestions are much appreciated. Thanks!

- John Underwood
--
View this message in context: http://grails.1312388.n4.nabble.com/Multiple-login-forms-and-authentication-providers-tp2553674p2553674.html
Sent from the Grails - user mailing list archive at Nabble.com.

---------------------------------------------------------------------
To unsubscribe from this list, please visit:

http://xircles.codehaus.org/manage_email
Burt Beckwith
2010-09-24 15:54:15 UTC
Permalink
Are you using a plugin or implementing this directly?

Burt
Post by jnunderwood
Hello,
We are creating our first Grails app. We are enjoying it, but we have had to
learn a lot in a short period of time. I am in charge of the security
aspects of the project.
Our project has a particular authentication requirement. Most users will use
a login form which uses LDAP for authentication. However, some users do not
have LDAP accounts; they will need to use a different login form which will
use a database for authentication.
How should I approach this problem? I have figured out how to authenticate
with either the database OR with LDAP. But I don't know how to provide users
the option of choosing which authentication mechanism to use.
Any suggestions are much appreciated. Thanks!
- John Underwood
jnunderwood
2010-09-24 16:03:32 UTC
Permalink
I have been able to use the spring-security-core and spring-security-ldap
plugins to implement each requirement separately. I just don't know how to
approach the problem of allowing multiple authentication mechanisms.

BTW, thank you very much for those plugins and the documentation!

- John Underwood
--
View this message in context: http://grails.1312388.n4.nabble.com/Multiple-login-forms-and-authentication-providers-tp2553674p2553693.html
Sent from the Grails - user mailing list archive at Nabble.com.

---------------------------------------------------------------------
To unsubscribe from this list, please visit:

http://xircles.codehaus.org/manage_email
Burt Beckwith
2010-09-24 16:28:43 UTC
Permalink
It should work that way already as long as the LDAP provider is before the db provider in the list (which should be the case). That way the LDAP provider attempts a login and fails, but then the db authentication succeeds and the user is authenticated.

There was a bug related to this but it was fixed - what version of the plugins are you using?

It'd be possible to allow allow a user with an LDAP account to authenticate using the db if that's necessary but it would require a couple of custom classes.

Burt
Post by jnunderwood
I have been able to use the spring-security-core and spring-security-ldap
plugins to implement each requirement separately. I just don't know how to
approach the problem of allowing multiple authentication mechanisms.
BTW, thank you very much for those plugins and the documentation!
- John Underwood
jnunderwood
2010-09-24 18:21:20 UTC
Permalink
I forgot to mention that while the LDAP login uses the typical
username/password scheme, the DB login requires four different pieces of
information, not username/password. This is why I am thinking of using two
different login forms.

I am using version 1.0.1 of the spring-security plugins.

- John Underwood
--
View this message in context: http://grails.1312388.n4.nabble.com/Multiple-login-forms-and-authentication-providers-tp2553674p2565892.html
Sent from the Grails - user mailing list archive at Nabble.com.

---------------------------------------------------------------------
To unsubscribe from this list, please visit:

http://xircles.codehaus.org/manage_email
Burt Beckwith
2010-09-24 18:46:06 UTC
Permalink
How have you configured the LDAP login to use four fields?

The problem I see is that it's easy enough to have two login pages and when you display explicit login links, you have one for each to allow the user to choose. But when a user clicks on a guarded link and gets redirected to the login page, I don't think you have any way of sending them to the correct one, so you'd need to display both.

I did this in the OpenID plugin using some simple Javascript that toggles the display of one of the two login forms: http://github.com/grails-plugins/grails-spring-security-openid/blob/master/src/templates/auth.gsp.template

Burt
Post by jnunderwood
I forgot to mention that while the LDAP login uses the typical
username/password scheme, the DB login requires four different pieces of
information, not username/password. This is why I am thinking of using two
different login forms.
I am using version 1.0.1 of the spring-security plugins.
- John Underwood
jnunderwood
2010-09-24 20:13:02 UTC
Permalink
We are only using the two fields (username/password) for LDAP. We are using
four different fields for DB authentication. We have done this before, using
javascript to visually toggle between two login forms like your OpenID
example, but we created a normal Java webapp instead of Grails. The toggle
will work fine for our situation.

Looking at your OpenID example, it looks like you are using two different
URLs for the form actions. Are these going to two different controllers? Or
are the mapped to the same controller? I think the part I'm confused about
is how/where to handle the two different form submissions.

- John Underwood
--
View this message in context: http://grails.1312388.n4.nabble.com/Multiple-login-forms-and-authentication-providers-tp2553674p2586395.html
Sent from the Grails - user mailing list archive at Nabble.com.

---------------------------------------------------------------------
To unsubscribe from this list, please visit:

http://xircles.codehaus.org/manage_email
Burt Beckwith
2010-09-24 20:21:34 UTC
Permalink
Spring Security doesn't use controllers for authentication, just to display the login form and error pages - everything is implemented using servlet filters.

OpenID has its own filter so it has its own URL but both LDAP and db auth use UsernamePasswordAuthenticationFilter and post to /j_spring_security_check. It works in the general case because as I described before if there are multiple providers as long as one succeeds then the authentication goes through.

So how are you processing the four fields for db auth?

Burt
Post by jnunderwood
We are only using the two fields (username/password) for LDAP. We are using
four different fields for DB authentication. We have done this before, using
javascript to visually toggle between two login forms like your OpenID
example, but we created a normal Java webapp instead of Grails. The toggle
will work fine for our situation.
Looking at your OpenID example, it looks like you are using two different
URLs for the form actions. Are these going to two different controllers? Or
are the mapped to the same controller? I think the part I'm confused about
is how/where to handle the two different form submissions.
- John Underwood
jnunderwood
2010-09-24 20:36:05 UTC
Permalink
Unfortunately, I misspoke earlier regarding DB authentication. We had gotten
it to work, but it was before we introduced spring-security. So, as of right
now, we only have LDAP working through spring-security.

It sounds like maybe I need to create a custom spring-security filter to
handle our special DB authentication requirements? Would I need a custom
authentication provider?

Sorry for being so confused. Grails is still very new to me and it took a
lot of effort to get LDAP working (partly because we use Active Directory
for user authentication and a database for roles). After doing all that, I
think I may have missed something fairly basic.

- John Underwood
--
View this message in context: http://grails.1312388.n4.nabble.com/Multiple-login-forms-and-authentication-providers-tp2553674p2590815.html
Sent from the Grails - user mailing list archive at Nabble.com.

---------------------------------------------------------------------
To unsubscribe from this list, please visit:

http://xircles.codehaus.org/manage_email
Burt Beckwith
2010-09-25 03:11:54 UTC
Permalink
A custom filter would probably be the most straightforward way. Base it on UsernamePasswordAuthenticationFilter and have it intercept its own URL. Keep in mind that the plugin subclasses UsernamePasswordAuthenticationFilter with RequestHolderAuthenticationFilter to populate SecurityRequestHolder. You should probably keep that functionality.

Register the filter as a bean in resources.groovy, e.g.

import com.yourcompany.yourapp.MyDbAuthenticationFilter

beans = {

myDbAuthenticationFilter(MyDbAuthenticationFilter) {
...
}
}

and add it to the filter chain in BootStrap.groovy using

SpringSecurityUtils.clientRegisterFilter('myDbAuthenticationFilter',
SecurityFilterPosition.FORM_LOGIN_FILTER.order + 10)

See section 16 in http://burtbeckwith.github.com/grails-spring-security-core/docs/manual/ for more details on clientRegisterFilter().

There's no convenient way to make the extra parameters available to a custom UserDetailsService, but that's just used by DaoAuthenticationProvider. So I'd go with a custom AuthenticationProvider that combines the logic and checks done by DaoAuthenticationProvider (i.e. account locked, disabled, etc.) with the lookup done by a UserDetailsService.

The process for a custom Authentication Provider is similar to adding a filter and is described in section 10 of the docs. Register the bean in resources.groovy and add it to the providerNames property in Config.groovy:

grails.plugins.springsecurity.providerNames = [
'myAuthenticationProvider',
'ldapAuthProvider',
'anonymousAuthenticationProvider',
'rememberMeAuthenticationProvider']

You'll need a custom Authentication token class to hold the four attributes - base it on UsernamePasswordAuthenticationToken. Since your provider will only support it and the LDAP provider won't, the order of the two providers isn't important (but they need to be before the anonymous and remember-me providers).

Burt
Post by jnunderwood
Unfortunately, I misspoke earlier regarding DB authentication. We had gotten
it to work, but it was before we introduced spring-security. So, as of right
now, we only have LDAP working through spring-security.
It sounds like maybe I need to create a custom spring-security filter to
handle our special DB authentication requirements? Would I need a custom
authentication provider?
Sorry for being so confused. Grails is still very new to me and it took a
lot of effort to get LDAP working (partly because we use Active Directory
for user authentication and a database for roles). After doing all that, I
think I may have missed something fairly basic.
- John Underwood
Loading...