如何获取自定义用户详细信息而不是Principal?

时间:2018-06-06 00:22:24

标签: spring-security spring-oauth2

我使用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

的实例

1 个答案:

答案 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