我使用Spring OAuth2服务器获得Spring SSO应用程序。
这是我的application.yml
:
security:
basic:
enabled: false
oauth2:
client:
clientId: atlas
clientSecret: cerberus
accessTokenUri: http://localhost:8180/guardiao/oauth/token
userAuthorizationUri: http://localhost:8180/guardiao/oauth/authorize
resource:
userInfoUri: http://localhost:8180/guardiao/user/me
当用户尝试从应用程序访问任何URL时,它会重定向到OAuth服务器登录。登录后,用户将被发送回应用程序。
然后,应用程序会向OAuth服务器询问用户详细信息(http://localhost:8180/guardiao/user/me
):
@RequestMapping("/user/me")
public @ResponseBody Principal user(Principal principal) {
System.out.println("Requesting logged user..." + principal.getName() );
return principal;
}
主要对象被发送到应用程序。一切正常。
我的问题:有没有办法:
1)在客户端拦截提交的Principal对象并向服务器询问用户是否补充?
@RequestMapping(value = "/user/{id}", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
public @ResponseBody MyCustomUser getUser(@PathVariable("id") long id) {
System.out.println("Fetching User with id " + id);
// get from database by ID (the Principal's username attribute)
return user;
}
2)在第一次请求时发送完整的用户详细信息(/user/me
)?我认为这可能会在客户端造成麻烦,因为它期待一个Principal对象......
这是Principal(me
端点)
{
"authorities": [
{
"authority": "ROLE_ADMIN"
}
],
"details": {
"remoteAddress": "0:0:0:0:0:0:0:1",
"sessionId": null,
"tokenValue": "eeddd69d-a6f1-488c-aec3-985ed71d4ee0",
"tokenType": "Bearer",
"decodedDetails": null
},
"authenticated": true,
"userAuthentication": {
"authorities": [
{
"authority": "ROLE_ADMIN"
}
],
"details": {
"grant_type": "password",
"username": "admin"
},
"authenticated": true,
"principal": {
"password": null,
"username": "admin",
"authorities": [
{
"authority": "ROLE_ADMIN"
}
],
"accountNonExpired": true,
"accountNonLocked": true,
"credentialsNonExpired": true,
"enabled": true
},
"credentials": null,
"name": "admin"
},
"principal": {
"password": null,
"username": "admin",
"authorities": [
{
"authority": "ROLE_ADMIN"
}
],
"accountNonExpired": true,
"accountNonLocked": true,
"credentialsNonExpired": true,
"enabled": true
},
"oauth2Request": {
"clientId": "cerberus",
"scope": [
"read",
"write",
"trust",
"user_info"
],
"requestParameters": {
"grant_type": "password",
"username": "admin"
},
"resourceIds": [],
"authorities": [
{
"authority": "ROLE_TRUSTED_CLIENT"
},
{
"authority": "ROLE_CLIENT"
}
],
"approved": true,
"refresh": false,
"redirectUri": null,
"responseTypes": [],
"extensions": {},
"grantType": "password",
"refreshTokenRequest": null
},
"clientOnly": false,
"credentials": "",
"name": "admin"
}
这是我的自定义用户:
{
"id": 1,
"username": "admin",
"fullName": "Administrator",
"enabled": true,
"roles": [
{
"id": 1,
"roleName": "ROLE_ADMIN"
}
],
"profileImage": "nophoto.png",
"funcao": "Cerberus Admin",
"setor": "",
"telefone": "",
"origem": "Subsystem Init",
"admin": true
}
我可以看到返回的对象是org.springframework.security.oauth2.provider.OAuth2Authentication
答案 0 :(得分:0)
我发现系统并不关心我作为回应传递的内容。
@RequestMapping("/user/me")
public @ResponseBody MyCustomUser user(Principal principal) {
MyCustomUser customUser = new MyCustomUser( this.userService.getUserByUsername( principal.getName() ) );
return customUser;
}
在客户端取回:
@RequestMapping(value = "/whoami", method = RequestMethod.GET, produces = "application/json")
public @ResponseBody OAuth2Authentication whoami( Principal principal ) {
OAuth2Authentication user = (OAuth2Authentication)principal;
UsernamePasswordAuthenticationToken authentication = (UsernamePasswordAuthenticationToken)user.getUserAuthentication();
Map<String, Object> details = ( Map<String, Object> ) authentication.getDetails();
for ( Map.Entry<String, Object> entry : details.entrySet() ) {
String key = entry.getKey();
Object value = entry.getValue();
System.out.println(" > " + key + " : " + value.getClass().getName() );
}
}
有人可以告诉我为什么LinkedHashMap
代替MyCustomUser
?