在 grails 中与开放 id 的 Spring 安全集成
Posted
技术标签:
【中文标题】在 grails 中与开放 id 的 Spring 安全集成【英文标题】:Spring security integration with open id in grails 【发布时间】:2012-02-14 02:50:19 【问题描述】:我正在使用 springsecurity 核心和 springsecurity openid 插件为我的 grails 应用程序集成 spring security 和 openId。我已经集成了它,它运行良好,但我需要访问已登录人员的电子邮件。我怎么能得到它,我能访问的只是一个用于识别人的令牌。
【问题讨论】:
【参考方案1】:感谢伊恩·罗伯茨。 他给了我这个回复,正好解决了我的问题。 他的回复是:
碰巧我在我的一个应用程序中实现了这一点 昨天:-) 不幸的是它不是一个开源应用程序所以我不能只是 指出我的代码,但我可以解释我做了什么。
spring-security-openid 插件支持“属性交换” OpenID 的机制,尽管支持的文档不多(如果在 全部)。它的工作情况取决于远端的提供商,但这 至少使用 Google 和 Yahoo 对我有用。
为了向提供商请求电子邮件地址,您需要添加 以下为 Config.groovy:
grails.plugins.springsecurity.openid.registration.requiredAttributes.email =“http://axschema.org/contact/email”
现在要将其连接到您的用户注册过程中,您需要一封电子邮件 S2 用户域类中的字段,您需要编辑生成的 OpenIdController.groovy 在几个地方。
将电子邮件属性添加到 OpenIdRegisterCommand
在 createAccount 操作中有一行 "if(!createNewAccount(...))" 传递用户名、密码和 openid 作为参数。将其与方法定义一起更改为 传递整个命令对象,而不仅仅是这两个字段。
在 createNewAccount 中从命令中向前传递电子邮件值 对象到用户域对象构造函数。
最后为您的电子邮件添加一个输入字段 grails-app/views/openId/createAccount.gsp.
您可以对其他属性(例如全名)执行相同操作。
grails.plugins.springsecurity.openid.registration.requiredAttributes.fullname = "http://axschema.org/namePerson"
将它连接在一起的重要一点是最后一个 requiredAttributes 后面的点(本例中为全名)必须匹配 OpenIdRegisterCommand 上的属性名称。
问候 查鲁耆那教
【讨论】:
我已验证此方法有效,并且有更多信息。上述步骤不仅会获取电子邮件,还会在创建时将其与新用户相关联。如果您只想在身份验证过程中从会话中访问电子邮件(即:从 OpenIdController createAccount 函数中),您可以使用 session[OIAFH.LAST_OPENID_ATTRIBUTES] 字符串对象来实现。【参考方案2】:我从未使用过 springsecurity openid 插件,但是在使用 springsecurity 核心时,您可以通过实现自定义 UserDetails
来公开有关当前用户的其他信息。在我的应用程序中,我添加了这个实现,以便我可以显示登录用户的name
属性。您需要稍作更改,以便显示电子邮件地址
/**
* 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
然后您需要创建UserDetailsService
的自定义实现,它返回上述类的实例
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)
您需要将此类的一个实例注册为名为@987654326@ 的Spring bean。我通过将以下内容添加到 Resources.groovy
userDetailsService(UserDetailsService)
【讨论】:
以上是关于在 grails 中与开放 id 的 Spring 安全集成的主要内容,如果未能解决你的问题,请参考以下文章
Grails 2.1.1 和 Spring Security Core 插件
Auth0 + Grails 3 + Spring Security
如何在 Spring Security 中指定 Open ID Realm?
Grails 3 Spring Security 覆盖登录表单