OAuth2AuthenticationToken 在 getAccount JHipster 6.0.1 中未被识别
OAuth2AuthenticationToken not been recognized in getAccount JHipster 6.0.1
我有一个本机 android 客户端,对我的 JHipster 单体应用程序进行 OAuth2 身份验证。它与 JHipster 版本 5.7.2
一起正常工作,但现在我使用的是版本 6.0.1
,我无法通过使用 AccountResource
中的 getAccount(Principal principal)
方法获取当前用户 class。 keycloak 发送的对象不是 OAuth2AuthenticationToken
class 的实例,所以我得到一个 Exception "User could not be found"
在以前的版本中,我曾经得到一个工作正常的 OAuth2Authentication
对象。
我以前收到的对象是这样的:
{
"storedRequest": {
"resourceIds": [
],
"authorities": [
],
"approved": true,
"responseTypes": [
],
"extensions": {
},
"clientId": "web_app",
"scope": [
],
"requestParameters": {
}
},
"userAuthentication": {
"principal": "Admin Administrator",
"credentials": "N/A",
"authorities": [
{
"role": "ROLE_USER"
}
],
"details": {
"sub": "f348bbbb-9441-4543-9940-9da31e50d877",
"email_verified": true,
"roles": [
"offline_access",
"ROLE_ADMIN",
"uma_authorization"
],
"name": "Admin Administrator",
"preferred_username": "admin",
"given_name": "Admin",
"family_name": "Administrator",
"email": "admin@localhost"
},
"authenticated": true
},
"authorities": [
{
"role": "ROLE_USER"
}
],
"details": {
"remoteAddress": "192.168.0.14",
"tokenValue": "eyJhbGciOiJ...",
"tokenType": "Bearer",
"display": "remoteAddress\u003d192.168.0.14, tokenType\u003dBearertokenValue\u003d\u003cTOKEN\u003e"
},
"authenticated": true
}
这是我现在收到的版本 6.0.1
:
"token": {
"headers": {
"kid": "w4uKMWW49GwLl-gakp9tAo6su7nAdddpo9Ul1pYABJo",
"typ": "JWT",
"alg": "RS256"
},
"claims": {
"sub": "f348bbbb-9441-4543-9940-9da31e50d877",
"resource_access": {
"web_app": {
"roles": [
"ROLE_USER",
"ROLE_ADMIN"
]
},
"account": {
"roles": [
"manage-account",
"manage-account-links",
"view-profile"
]
}
},
"email_verified": true,
"allowed-origins": [
"*"
],
"iss": "http://192.168.0.12:9080/auth/realms/jhipster",
"typ": "Bearer",
"preferred_username": "admin",
"given_name": "Admin",
"aud": [
"web_app",
"account"
],
"acr": "0",
"nbf": {
"seconds": 0,
"nanos": 0
},
"realm_access": {
"roles": [
"offline_access",
"ROLE_ADMIN",
"uma_authorization"
]
},
"azp": "android_app",
"auth_time": 1559622495,
"scope": "openid profile email jhipster",
"name": "Admin Administrator",
"exp": {
"seconds": 1559622877,
"nanos": 0
},
"session_state": "6c756fb9-c335-4a23-9c50-ed5adeb42456",
"iat": {
"seconds": 1559622577,
"nanos": 0
},
"family_name": "Administrator",
"jti": "6fe0962c-18c1-471e-b4c0-ad3afda12b46",
"email": "admin@localhost"
},
"tokenValue": "eyJhbG...",
"issuedAt": {
"seconds": 1559622577,
"nanos": 0
},
"expiresAt": {
"seconds": 1559622877,
"nanos": 0
}
},
"authorities": [
{
"role": "SCOPE_openid"
},
{
"role": "SCOPE_profile"
},
{
"role": "SCOPE_email"
},
{
"role": "SCOPE_jhipster"
}
],
"details": {
"remoteAddress": "192.168.0.14"
},
"authenticated": true
}
我希望收到的 Principal
对象是 OAuth2AuthenticationToken
的一个实例。有什么建议吗?
好吧,我意识到我得到的对象是 JwtAuthenticationToken
,所以我对 getAccount()
方法做了一些修改,以便在接收这种类型的令牌时达到目的。我还在接收 JwtAuthenticationToken 时为 getUserFromAuthentication()
添加了一个新的参数选项。
@GetMapping("/account")
@SuppressWarnings("unchecked")
public UserDTO getAccount(Principal principal) {
if (principal instanceof OAuth2AuthenticationToken) {
return userService.getUserFromAuthentication((OAuth2AuthenticationToken) principal);
} else if (principal instanceof JwtAuthenticationToken) {
return userService.getUserFromAuthentication((JwtAuthenticationToken) principal);
} else {
throw new AccountResourceException("User could not be found");
}
}
public UserDTO getUserFromAuthentication(JwtAuthenticationToken principal) {
Map<String, Object> attributes = principal.getToken().getClaims();
User user = getUser(attributes);
Map<String, Object> resourceAccess = (Map<String, Object>) principal.getToken().getClaims().get("resource_access");
JSONObject webApp = (JSONObject) resourceAccess.get("web_app");
JSONArray roles = (JSONArray) webApp.get("roles");
user.setAuthorities(roles.stream().map(authority -> {
Authority auth = new Authority();
auth.setName(authority.toString());
return auth;
}).collect(Collectors.toSet()));
return new UserDTO(syncUserWithIdP(attributes, user));
}
我有一个本机 android 客户端,对我的 JHipster 单体应用程序进行 OAuth2 身份验证。它与 JHipster 版本 5.7.2
一起正常工作,但现在我使用的是版本 6.0.1
,我无法通过使用 AccountResource
中的 getAccount(Principal principal)
方法获取当前用户 class。 keycloak 发送的对象不是 OAuth2AuthenticationToken
class 的实例,所以我得到一个 Exception "User could not be found"
在以前的版本中,我曾经得到一个工作正常的 OAuth2Authentication
对象。
我以前收到的对象是这样的:
{
"storedRequest": {
"resourceIds": [
],
"authorities": [
],
"approved": true,
"responseTypes": [
],
"extensions": {
},
"clientId": "web_app",
"scope": [
],
"requestParameters": {
}
},
"userAuthentication": {
"principal": "Admin Administrator",
"credentials": "N/A",
"authorities": [
{
"role": "ROLE_USER"
}
],
"details": {
"sub": "f348bbbb-9441-4543-9940-9da31e50d877",
"email_verified": true,
"roles": [
"offline_access",
"ROLE_ADMIN",
"uma_authorization"
],
"name": "Admin Administrator",
"preferred_username": "admin",
"given_name": "Admin",
"family_name": "Administrator",
"email": "admin@localhost"
},
"authenticated": true
},
"authorities": [
{
"role": "ROLE_USER"
}
],
"details": {
"remoteAddress": "192.168.0.14",
"tokenValue": "eyJhbGciOiJ...",
"tokenType": "Bearer",
"display": "remoteAddress\u003d192.168.0.14, tokenType\u003dBearertokenValue\u003d\u003cTOKEN\u003e"
},
"authenticated": true
}
这是我现在收到的版本 6.0.1
:
"token": {
"headers": {
"kid": "w4uKMWW49GwLl-gakp9tAo6su7nAdddpo9Ul1pYABJo",
"typ": "JWT",
"alg": "RS256"
},
"claims": {
"sub": "f348bbbb-9441-4543-9940-9da31e50d877",
"resource_access": {
"web_app": {
"roles": [
"ROLE_USER",
"ROLE_ADMIN"
]
},
"account": {
"roles": [
"manage-account",
"manage-account-links",
"view-profile"
]
}
},
"email_verified": true,
"allowed-origins": [
"*"
],
"iss": "http://192.168.0.12:9080/auth/realms/jhipster",
"typ": "Bearer",
"preferred_username": "admin",
"given_name": "Admin",
"aud": [
"web_app",
"account"
],
"acr": "0",
"nbf": {
"seconds": 0,
"nanos": 0
},
"realm_access": {
"roles": [
"offline_access",
"ROLE_ADMIN",
"uma_authorization"
]
},
"azp": "android_app",
"auth_time": 1559622495,
"scope": "openid profile email jhipster",
"name": "Admin Administrator",
"exp": {
"seconds": 1559622877,
"nanos": 0
},
"session_state": "6c756fb9-c335-4a23-9c50-ed5adeb42456",
"iat": {
"seconds": 1559622577,
"nanos": 0
},
"family_name": "Administrator",
"jti": "6fe0962c-18c1-471e-b4c0-ad3afda12b46",
"email": "admin@localhost"
},
"tokenValue": "eyJhbG...",
"issuedAt": {
"seconds": 1559622577,
"nanos": 0
},
"expiresAt": {
"seconds": 1559622877,
"nanos": 0
}
},
"authorities": [
{
"role": "SCOPE_openid"
},
{
"role": "SCOPE_profile"
},
{
"role": "SCOPE_email"
},
{
"role": "SCOPE_jhipster"
}
],
"details": {
"remoteAddress": "192.168.0.14"
},
"authenticated": true
}
我希望收到的 Principal
对象是 OAuth2AuthenticationToken
的一个实例。有什么建议吗?
好吧,我意识到我得到的对象是 JwtAuthenticationToken
,所以我对 getAccount()
方法做了一些修改,以便在接收这种类型的令牌时达到目的。我还在接收 JwtAuthenticationToken 时为 getUserFromAuthentication()
添加了一个新的参数选项。
@GetMapping("/account")
@SuppressWarnings("unchecked")
public UserDTO getAccount(Principal principal) {
if (principal instanceof OAuth2AuthenticationToken) {
return userService.getUserFromAuthentication((OAuth2AuthenticationToken) principal);
} else if (principal instanceof JwtAuthenticationToken) {
return userService.getUserFromAuthentication((JwtAuthenticationToken) principal);
} else {
throw new AccountResourceException("User could not be found");
}
}
public UserDTO getUserFromAuthentication(JwtAuthenticationToken principal) {
Map<String, Object> attributes = principal.getToken().getClaims();
User user = getUser(attributes);
Map<String, Object> resourceAccess = (Map<String, Object>) principal.getToken().getClaims().get("resource_access");
JSONObject webApp = (JSONObject) resourceAccess.get("web_app");
JSONArray roles = (JSONArray) webApp.get("roles");
user.setAuthorities(roles.stream().map(authority -> {
Authority auth = new Authority();
auth.setName(authority.toString());
return auth;
}).collect(Collectors.toSet()));
return new UserDTO(syncUserWithIdP(attributes, user));
}