Return 关于用户创建端点的 OAuth 令牌信息

Return OAuth Token information on user creation endpoint

我目前正在使用 Spring 引导实现 REST Api,并通过 OAuth2 进行保护。这是我目前的情况:

  1. 用户注册端点、示例成功响应和控制器方法实现

POST http://<host>/users/register

{
  "id": "6061b5c0-a817-4fff-ba1f-c7f4e94080ed",
  "name": "Name",
  "email": "user@email.com",
  "password": "a$R7yw/HbLmFzMpkzsWOqLp.I.itHRo7B/9MXKNrpArvK/Lfta0Z.I.",
  "createdAt": "2019-12-14T22:00:46.682+0000"
  ...
}
@PostMapping(value = "/register")
public ResponseEntity<User> register(@RequestBody final User user) {
    final User createdUser = mUsersService.create(user);
    return new ResponseEntity<>(createdUser, HttpStatus.CREATED);
}
  1. 令牌端点和示例响应

POST http://<host>/oauth/token

{
  "access_token": "03bd76f0-20bd-45ef-9adb-b0903345e590",
  "token_type": "bearer",
  "refresh_token": "a1022bbd-407a-4899-b1b0-20a889ed0419",
  "expires_in": 82373,
  "scope": "read write"
}

如何在 /users/register 端点上 return 令牌 JSON(由 /oauth/token 端点 return 编辑)。

使用下面的方法,

private OAuth2AccessToken getToken(LoginResource loginResource) {
    String access_token_url = "http://localhost:8080/api/oauth/token";
    ResourceOwnerPasswordResourceDetails resourceDetails = new ResourceOwnerPasswordResourceDetails();
    resourceDetails.setGrantType("password");
    resourceDetails.setAccessTokenUri(access_token_url);

    //-- set the clients info
    resourceDetails.setClientId("clientId");
    resourceDetails.setClientSecret("clientSecret");

    // set scopes
    List<String> scopes = new ArrayList<>();
    scopes.add("read"); 
    scopes.add("write");
    scopes.add("trust");
    resourceDetails.setScope(scopes);

    //-- set Resource Owner info
    resourceDetails.setUsername(loginResource.getUserName());
    resourceDetails.setPassword(loginResource.getPassword());
    OAuth2RestTemplate oAuth2RestTemplate = new OAuth2RestTemplate(resourceDetails);
    return oAuth2RestTemplate.getAccessToken(); 
}

最后,在检查进入 /oauth/token 端点的数据后,我得出以下解决方案:

    private static final String PARAM_GRANT_TYPE = "grant_type";
    private static final String PARAM_USERNAME = "username";
    private static final String PARAM_PASSWORD = "password";
    private static final String PARAM_GRANT_TYPE_VALUE_PASSWORD = "password";

    @Autowired
    private UsersService mUsersService;

    @Autowired
    private TokenEndpoint mTokenEndpoint;

    @PostMapping(value = "/register")
    public ResponseEntity<OAuth2AccessToken> register(final Principal principal,
                                                      @RequestParam final String name,
                                                      @RequestParam final String email,
                                                      @RequestParam final String password) throws HttpRequestMethodNotSupportedException {
        final User user = mUsersService.create(name, email, password);

        final Map<String, String> tokenParameters = new HashMap<>(3);
        tokenParameters.put(PARAM_GRANT_TYPE, PARAM_GRANT_TYPE_VALUE_PASSWORD);
        tokenParameters.put(PARAM_USERNAME, email);
        tokenParameters.put(PARAM_PASSWORD, password);

        return mTokenEndpoint.postAccessToken(principal, tokenParameters);
    }

我所做的是使用转发的主体(在我的例子中是客户端身份验证)和正常的 password grant_type 参数调用 POST 令牌端点。