如何在Grails 3.3.5+Spring-security-rest登录响应中添加用户信息
如何在Spring Security REST登录响应中添加额外用户信息?
刚好我之前也处理过类似需求,按照你提到的Spring Security REST文档指引,咱们分三步就能实现:
1. 自定义UserDetailsService,封装额外用户信息
首先需要创建一个自定义的UserDetailsService实现类,用来从你的数据源(比如数据库)获取用户的额外信息(比如姓名、ID等),并把这些信息存入自定义的GrailsUser对象中:
import grails.plugin.springsecurity.userdetails.GrailsUser import grails.plugin.springsecurity.userdetails.GrailsUserDetailsService import org.springframework.security.core.userdetails.UserDetails import org.springframework.security.core.userdetails.UsernameNotFoundException class CustomUserDetailsService implements GrailsUserDetailsService { @Override UserDetails loadUserByUsername(String username, boolean loadRoles) throws UsernameNotFoundException { // 替换为你实际查询用户的逻辑,比如从User域类根据邮箱查询 def user = User.findByEmail(username) if (!user) { throw new UsernameNotFoundException("用户不存在:$username") } // 处理用户角色,转换为Spring Security需要的Authority对象 def authorities = user.authorities.collect { new org.springframework.security.core.authority.SimpleGrantedAuthority(it.authority) } // 自定义GrailsUser实例,将额外信息(比如realName、id)封装进去 return new GrailsUser(user.email, user.password, user.enabled, !user.accountExpired, !user.passwordExpired, !user.accountLocked, authorities, user.id) { final String realName = user.realName // 可根据需求添加更多字段,比如phoneNumber等 } } @Override UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { return loadUserByUsername(username, true) } }
2. 自定义AccessTokenJsonRenderer,渲染额外信息
接下来创建一个自定义的AccessTokenJsonRenderer,用来从认证令牌的principal中取出额外信息,并添加到登录响应的JSON里:
import grails.plugin.springsecurity.rest.token.rendering.AccessTokenJsonRenderer import grails.plugin.springsecurity.rest.token.rendering.DefaultAccessTokenJsonRenderer import org.springframework.security.core.Authentication import grails.converters.JSON class CustomAccessTokenJsonRenderer implements AccessTokenJsonRenderer { private final DefaultAccessTokenJsonRenderer defaultRenderer = new DefaultAccessTokenJsonRenderer() @Override String generateJson(Authentication authentication) { // 先获取默认的响应JSON数据 def defaultJson = defaultRenderer.generateJson(authentication) def parsedJson = JSON.parse(defaultJson) // 从principal中提取自定义的额外信息 def principal = authentication.principal if (principal instanceof GrailsUser) { // 添加你需要的字段到响应中 parsedJson.realName = principal.realName parsedJson.userId = principal.id // 可继续添加其他字段,比如phoneNumber等 } // 返回修改后的JSON字符串 return parsedJson as JSON } }
3. 注册自定义Bean,替换默认实现
最后在grails-app/conf/spring/resources.groovy中注册这两个自定义Bean,让Spring Security使用我们的实现:
beans = { // 替换默认的userDetailsService userDetailsService(CustomUserDetailsService) // 替换默认的accessTokenJsonRenderer accessTokenJsonRenderer(CustomAccessTokenJsonRenderer) }
完成以上配置后,再次调用/api/login接口,你就能得到包含额外信息的响应了,示例如下:
{ "username": "name.surname@acme.com", "roles": [ "ROLE_USER" ], "access_token": "qgsbpk05jfrbf33xx08m8r4govkg53d1", "realName": "Name Surname", "userId": 123 }
内容的提问来源于stack exchange,提问作者NiBE
相关产品推荐
相关产品推荐

