为什么我在访问令牌时在Spring Oauth2中收到未经授权的401错误?

时间:2016-05-15 17:14:13

标签: java spring curl oauth

您好我正在我的项目中实现Spring Oauth 2框架,我在请求访问令牌时遇到401未经授权的错误,下面是我的代码。

public class Test {


    public static void main(String[] args) {

        RestTemplate restTemplate=new RestTemplate();
        Map<String, String> map=new HashMap<String, String>();
        map.put("grant_type", "password");
        map.put("client_id", "test");
        map.put("client_secret", "test");
        map.put("username", "test");
        map.put("password", "test");
        String url="http://localhost:8080/SpringOauthServer/oauth/token?grant_type={grant_type}&client_id={client_id}&client_secret={client_secret}&username={username}&password={password}";

        OauthToken result=restTemplate.getForObject(url, OauthToken.class,map);     
        System.out.println(result.getAccess_token());
    }


}

但是当我使用下面的curl命令时,我获得了访问令牌。请帮我,我在误解...

curl test:test@localhost:8080/SpringOauthServer/oauth/token -d grant_type=password -d client_id=test -d client_secret=test -d username=test   -d password=test

响应:

{
   "access_token":"d83a312b-323a-40a9-bfc4-c431c40f2ca8",
   "token_type":"bearer",
   "refresh_token":"17976f94-f3b7-4e2d-8726-3d094f7b1061",
   "expires_in":43190,
   "scope":"read write trust"
}

1 个答案:

答案 0 :(得分:1)

我知道这是一个老线程但是如果有人坚持使用RestTemplateOAuth2(例如,用于集成测试),这应该如何工作。

使用access_token

获取OAuth2 RestTemplate

在上述问题grant_type=password中,这意味着您需要在client_id http标头中发送secretauthorization作为基本身份验证,其余信息均为您的请求将作为表单数据发送到http请求正文。

重复使用问题中的示例:

public class Test {
    public static void main(String[] args) {
        RestTemplate restTemplate = new RestTemplate();

        // Add the basic authentication "username:password"
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);

        // Adding form data
        Map<String, String> map = new HashMap<String, String>();
        map.put("grant_type", "password");
        map.put("client_id", "test");
        map.put("username", "test");
        map.put("password", "test");
        map.put("scope", "read,write,trust");

        // Creating HttpEntity request with the headers and form data
        HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<>(map, headers);

        String url="http://localhost:8080/SpringOauthServer/oauth/token";

        // Execute the request
        ResponseEntity<String> response = 
            restTemplate
                .withBasicAuth("test", "test")
                .postForEntity(
                    url,
                    request,
                    OauthToken.class
                );

        System.out.println(result.getAccess_token());
    }
}

问题中出了什么问题:

问题函数中使用的curl与提供的java代码完全不同。

我会把它拆掉,不要忘记检查documentation here

  1. curl test:test使用基本身份验证调用curltest作为用户名,test作为密码(格式{USERNAME}:{PASSWORD}),我们也是这样做的在我们的RestTemplate中,它在java代码中缺失。

  2. localhost:8080/SpringOauthServer/oauth/token curl命令中使用的网址没有任何网址参数,我们在RestTemplate中做了同样的操作,但问题中添加了这个参数,这是错误的

  3. -d grant_type=password -d client_id=test -d client_secret=test -d username=test -d password=test使用-d标记参数会使curl执行http POST请求并将这些参数作为表单数据发送到http主体中,我们也是这样做的在我们的RestTemplate中,它在java代码中缺失。