Grails REST 安全性 - 将用户 ID 添加到令牌
Grails REST security - Add user id to token
我想将用户 ID 字段添加到从 /api/login
返回的令牌中
目前是:
{
"username": "user",
"roles": [
"ROLE_USER"
],
"token_type": "Bearer",
"access_token": "eyJhbGciOiJIUzI1NiJ9.2uk2YoHsyd7bqUdtUYN19ef..",
"expires_in": 3600,
"refresh_token": "eyJhbGciOiJIUzI1NiJ9.eyJwcmluY2lwYWwiOiJINH.."
}
我需要:
{
"id": "1",
"username": "user",
"roles": [
"ROLE_USER"
],
"token_type": "Bearer",
"access_token": "eyJhbGciOiJIUzI1NiJ9.2uk2YoHsyd7bqUdtUYN19ef..",
"expires_in": 3600,
"refresh_token": "eyJhbGciOiJIUzI1NiJ9.eyJwcmluY2lwYWwiOiJINH.."
}
目标 - 带有用户 ID 的查询,例如 POST /api/something
还有其他方法吗?
提前致谢
您没有提到 Grails 版本,所以我发布了我为 Grails 2.4.4 实现的答案
第一件事,您需要在 src/groovy
下创建的自定义 class 中实现 AccessTokenJsonRenderer
接口,如下所示。
import grails.plugin.springsecurity.SpringSecurityUtils
import grails.plugin.springsecurity.rest.token.AccessToken
import grails.plugin.springsecurity.rest.token.rendering.AccessTokenJsonRenderer
import groovy.json.JsonBuilder
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.security.core.GrantedAuthority
/**
* Created by Prakash Thete on 17/04/2018
*/
class CustomAppRestAuthTokenJsonRenderer implements AccessTokenJsonRenderer {
@Override
String generateJson(AccessToken accessToken){
// Add extra custom parameters if you want in this map to be rendered in login response
Map response = [
id : accessToken.principal.id,
username : accessToken.principal.username,
access_token : accessToken.accessToken,
token_type : "Bearer",
refresh_token: accessToken.refreshToken,
roles : accessToken.authorities.collect { GrantedAuthority role -> role.authority }
]
return new JsonBuilder( response ).toPrettyString()
}
}
您需要在 resources.groovy
中创建自定义 class 的 bean 的第二件事,如下所示
// For overriding the token json renderer
accessTokenJsonRenderer(CustomAppRestAuthTokenJsonRenderer)
现在点击 api/login
后,您将收到用户 ID 以及其他详细信息。
希望对您有所帮助!
如果您想在 Auth JSON 响应中添加有关用户的更多详细信息,您可以使用主体 ID 并按如下方式查询用户。
注意添加了@Transactional 注释。
import grails.gorm.transactions.Transactional
import grails.plugin.springsecurity.rest.token.AccessToken
import grails.plugin.springsecurity.rest.token.rendering.AccessTokenJsonRenderer
import groovy.json.JsonBuilder
import org.springframework.security.core.GrantedAuthority
@Transactional
class CustomAuthTokenRenderer implements AccessTokenJsonRenderer {
@Override
String generateJson(AccessToken accessToken) {
// User the principal ID to get an instance of the user from the database
User user = User.get accessToken.principal.id as Long
// Add extra custom parameters if you want in this map to be rendered in login response
Map res = [
id : user.id,
username : user.username,
firstName : user.firstName,
lastName : user.lastName,
profilePicture : user.profilePicture,
dateOfBirth : user.dob,
expiration : accessToken.expiration,
access_token : accessToken.accessToken,
token_type : "Bearer",
refresh_token : accessToken.refreshToken,
roles : accessToken.authorities.collect { GrantedAuthority role -> role.authority },
friends: user.friends.collect { Friend friend ->
[
id : friend.id,
firstName : friend.firstName,
dateCreated : friend.dateCreated,
lastUpdated : friend.lastUpdated,
]
}
]
return new JsonBuilder(res).toPrettyString()
}
}
无论您想向响应添加什么,使用用户对象,您几乎可以添加任何内容。只是不要试图进行太多查询,因为这会导致登录过程非常缓慢。
我想将用户 ID 字段添加到从 /api/login
返回的令牌中目前是:
{
"username": "user",
"roles": [
"ROLE_USER"
],
"token_type": "Bearer",
"access_token": "eyJhbGciOiJIUzI1NiJ9.2uk2YoHsyd7bqUdtUYN19ef..",
"expires_in": 3600,
"refresh_token": "eyJhbGciOiJIUzI1NiJ9.eyJwcmluY2lwYWwiOiJINH.."
}
我需要:
{
"id": "1",
"username": "user",
"roles": [
"ROLE_USER"
],
"token_type": "Bearer",
"access_token": "eyJhbGciOiJIUzI1NiJ9.2uk2YoHsyd7bqUdtUYN19ef..",
"expires_in": 3600,
"refresh_token": "eyJhbGciOiJIUzI1NiJ9.eyJwcmluY2lwYWwiOiJINH.."
}
目标 - 带有用户 ID 的查询,例如 POST /api/something 还有其他方法吗? 提前致谢
您没有提到 Grails 版本,所以我发布了我为 Grails 2.4.4 实现的答案
第一件事,您需要在 src/groovy
下创建的自定义 class 中实现 AccessTokenJsonRenderer
接口,如下所示。
import grails.plugin.springsecurity.SpringSecurityUtils
import grails.plugin.springsecurity.rest.token.AccessToken
import grails.plugin.springsecurity.rest.token.rendering.AccessTokenJsonRenderer
import groovy.json.JsonBuilder
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.security.core.GrantedAuthority
/**
* Created by Prakash Thete on 17/04/2018
*/
class CustomAppRestAuthTokenJsonRenderer implements AccessTokenJsonRenderer {
@Override
String generateJson(AccessToken accessToken){
// Add extra custom parameters if you want in this map to be rendered in login response
Map response = [
id : accessToken.principal.id,
username : accessToken.principal.username,
access_token : accessToken.accessToken,
token_type : "Bearer",
refresh_token: accessToken.refreshToken,
roles : accessToken.authorities.collect { GrantedAuthority role -> role.authority }
]
return new JsonBuilder( response ).toPrettyString()
}
}
您需要在 resources.groovy
中创建自定义 class 的 bean 的第二件事,如下所示
// For overriding the token json renderer
accessTokenJsonRenderer(CustomAppRestAuthTokenJsonRenderer)
现在点击 api/login
后,您将收到用户 ID 以及其他详细信息。
希望对您有所帮助!
如果您想在 Auth JSON 响应中添加有关用户的更多详细信息,您可以使用主体 ID 并按如下方式查询用户。
注意添加了@Transactional 注释。
import grails.gorm.transactions.Transactional
import grails.plugin.springsecurity.rest.token.AccessToken
import grails.plugin.springsecurity.rest.token.rendering.AccessTokenJsonRenderer
import groovy.json.JsonBuilder
import org.springframework.security.core.GrantedAuthority
@Transactional
class CustomAuthTokenRenderer implements AccessTokenJsonRenderer {
@Override
String generateJson(AccessToken accessToken) {
// User the principal ID to get an instance of the user from the database
User user = User.get accessToken.principal.id as Long
// Add extra custom parameters if you want in this map to be rendered in login response
Map res = [
id : user.id,
username : user.username,
firstName : user.firstName,
lastName : user.lastName,
profilePicture : user.profilePicture,
dateOfBirth : user.dob,
expiration : accessToken.expiration,
access_token : accessToken.accessToken,
token_type : "Bearer",
refresh_token : accessToken.refreshToken,
roles : accessToken.authorities.collect { GrantedAuthority role -> role.authority },
friends: user.friends.collect { Friend friend ->
[
id : friend.id,
firstName : friend.firstName,
dateCreated : friend.dateCreated,
lastUpdated : friend.lastUpdated,
]
}
]
return new JsonBuilder(res).toPrettyString()
}
}
无论您想向响应添加什么,使用用户对象,您几乎可以添加任何内容。只是不要试图进行太多查询,因为这会导致登录过程非常缓慢。