Reputation: 61
I am working on Integrating spring security with openId for my grails Application using springsecurity core and springsecurity openid plugins. I have integrated it, and it works well but I need to access the email for the logged in person. How can I get that, all that I am able to access is a token which is used for identifying the person.
Upvotes: 2
Views: 870
Reputation: 61
Thanks to Ian Roberts. He gives me this reply,Which exactly solves my problem. His reply was:
As it happens I implemented exactly this in one of my applications yesterday :-) Unfortunately it's not an open-source app so I can't just point you at my code but I can explain what I did.
The spring-security-openid plugin supports the "attribute exchange" mechanism of OpenID, although the support is not documented much (if at all). How well it works depends on the provider at the far end but this at least worked for me using Google and Yahoo.
In order to request the email address from the provider you need to add the following to Config.groovy:
grails.plugins.springsecurity.openid.registration.requiredAttributes.email = "http://axschema.org/contact/email"
Now to wire that into your user registration process you need an email field in your S2 user domain class, and you need to edit the generated OpenIdController.groovy in a few places.
add an email property to the OpenIdRegisterCommand
in the createAccount action there's a line "if(!createNewAccount(...))" which passes the username, password and openid as parameters. Change this along with the method definition to pass the whole command object instead of just these two fields.
in createNewAccount pass the email value forward from the command object to the User domain object constructor.
And finally add an input field for email to your grails-app/views/openId/createAccount.gsp.
You can do the same with other attributes such as full name.
grails.plugins.springsecurity.openid.registration.requiredAttributes.fullname = "http://axschema.org/namePerson"
The important thing to wire it together is that the thing after the last dot following requiredAttributes (fullname in this example) must match the name of the property on the OpenIdRegisterCommand.
Regards Charu Jain
Upvotes: 4
Reputation: 187499
I've never used the springsecurity openid plugin, but when using springsecurity core you can expose additional information about the current user by implmenting a custom UserDetails
. In my app, I added this implementation, so that I can show the name
property of logged-in users. You'll need to change this slightly, so that the email address is exposed instead
/**
* Custom implementation of UserDetails that exposes the user's name
* http://grails-plugins.github.com/grails-spring-security-core/docs/manual/guide/11%20Custom%20UserDetailsService.html
*/
class CustomUserDetails extends GrailsUser {
// additional property
final String name
CustomUserDetails(String username,
String password,
boolean enabled,
boolean accountNonExpired,
boolean credentialsNonExpired,
boolean accountNonLocked,
Collection<GrantedAuthority> authorities,
long id,
String displayName) {
super(username, password, enabled, accountNonExpired, credentialsNonExpired, accountNonLocked, authorities, id)
this.name = displayName
}
}
You then need to create a custom implementation of UserDetailsService
which returns instances of the class above
class UserDetailsService implements GrailsUserDetailsService {
/**
* Some Spring Security classes (e.g. RoleHierarchyVoter) expect at least one role, so
* we give a user with no granted roles this one which gets past that restriction but
* doesn't grant anything.
*/
static final List NO_ROLES = [new GrantedAuthorityImpl(SpringSecurityUtils.NO_ROLE)]
UserDetails loadUserByUsername(String username, boolean loadRoles) {
return loadUserByUsername(username)
}
UserDetails loadUserByUsername(String username) {
User.withTransaction { status ->
User user = User.findByUsername(username)
if (!user) {
throw new UsernameNotFoundException('User not found', username)
}
def authorities = user.authorities.collect {new GrantedAuthorityImpl(it.authority)}
return new CustomUserDetails(
user.username,
user.password,
user.enabled,
!user.accountExpired,
!user.passwordExpired,
!user.accountLocked,
authorities ?: NO_ROLES,
user.id,
user.name)
}
}
}
You need to register an instance of this class as a Spring bean named userDetailsService
. I did this by adding the following to Resources.groovy
userDetailsService(UserDetailsService)
Upvotes: 1