对AzureAD的请求格式错误

对AzureAD的请求格式错误,azure,spring-boot,spring-security,azure-active-directory,Azure,Spring Boot,Spring Security,Azure Active Directory,我有一个Spring启动应用程序,并通过Oauth2/Openid connect成功登录AzureAD。我能够从OAuth2User中看到用户的信息 现在,使用中记录的流程,我尝试从我的授权令牌开始获取accesstoken。我使用Apache httpclient执行以下操作: @GetMapping("current") public UserTo getCurrentUserInformation() throws IOException { OAuth2Aut

我有一个Spring启动应用程序,并通过Oauth2/Openid connect成功登录AzureAD。我能够从OAuth2User中看到用户的信息

现在,使用中记录的流程,我尝试从我的授权令牌开始获取accesstoken。我使用Apache httpclient执行以下操作:

@GetMapping("current")
 public UserTo getCurrentUserInformation() throws IOException {
  OAuth2AuthenticationToken auth = (OAuth2AuthenticationToken) SecurityContextHolder.getContext().getAuthentication();
  OAuth2AuthorizedClient client = clientService.loadAuthorizedClient(auth.getAuthorizedClientRegistrationId(), auth.getName());
  String accessToken = client.getAccessToken().getTokenValue();


  try (CloseableHttpClient httpclient = HttpClients.createDefault()) {
    List<NameValuePair> form = new ArrayList<>();
    form.add(new BasicNameValuePair("client_secret", "<configured client-secret>"));
    form.add(new BasicNameValuePair("grant_type", "authorization_code"));
    form.add(new BasicNameValuePair("code", accessToken));
    form.add(new BasicNameValuePair("client_id", "<configured client_id>"));
    form.add(new BasicNameValuePair("scope", "group.read.all user.read"));
    UrlEncodedFormEntity entity = new UrlEncodedFormEntity(form, Consts.UTF_8);

    HttpPost httpPost = new HttpPost("https://login.microsoftonline.com/<tenant id>/oauth2/v2.0/token");
    httpPost.setEntity(entity);
    System.out.println("Executing request " + httpPost.getRequestLine());

    // Create a custom response handler
    ResponseHandler<String> responseHandler = response -> {
        int status = response.getStatusLine().getStatusCode();
        if (status >= 200 && status < 300) {
            HttpEntity responseEntity = response.getEntity();
            return responseEntity != null ? EntityUtils.toString(responseEntity) : null;
        } else {
            throw new ClientProtocolException("Unexpected response status: " + status);
        }
    };
    String responseBody = httpclient.execute(httpPost, responseHandler);
    System.out.println("----------------------------------------");
    System.out.println(responseBody);
    return null;
}
@GetMapping(“当前”)
public UserTo getCurrentUserInformation()引发IOException{
OAuth2AuthenticationToken auth=(OAuth2AuthenticationToken)SecurityContextHolder.getContext().getAuthentication();
OAuth2AuthorizedClient=clientService.loadAuthorizedClient(auth.GetAuthorizedClient注册ID(),auth.getName());
字符串accessToken=client.getAccessToken().getTokenValue();
try(CloseableHttpClient-httpclient=HttpClients.createDefault()){
列表形式=新建ArrayList();
添加(新的BasicNameValuePair(“客户机密”);
添加(新的BasicNameValuePair(“授权类型”、“授权代码”);
添加(新的BasicNameValuePair(“代码”,accessToken));
添加(新的BasicNameValuePair(“客户id”);
添加(新的BasicNameValuePair(“scope”、“group.read.all user.read”);
UrlEncodedFormEntity实体=新的UrlEncodedFormEntity(表单,Consts.UTF_8);
HttpPost HttpPost=新的HttpPost(“https://login.microsoftonline.com//oauth2/v2.0/token");
httpPost.setEntity(实体);
System.out.println(“正在执行请求”+httpPost.getRequestLine());
//创建自定义响应处理程序
ResponseHandler ResponseHandler=响应->{
int status=response.getStatusLine().getStatusCode();
如果(状态>=200&&status<300){
HttpEntity responseEntity=response.getEntity();
return responseEntity!=null?EntityUtils.toString(responseEntity):null;
}否则{
抛出新的ClientProtocolException(“意外响应状态:+状态”);
}
};
字符串responseBody=httpclient.execute(httpPost,responseHandler);
System.out.println(“--------------------------------------------------------”;
系统输出打印LN(响应库);
返回null;
}
显然,;和对应的是实际值

正如您在下面的实际http调用日志中所看到的,我收到一个AADSTS9002313:无效请求。请求格式错误或无效

>POST/>内容长度:840
>>内容类型:application/x-www-form-urlencoded;字符集=UTF-8
>>主机:login.microsoftonline.com
>>连接:保持活力
>>用户代理:ApacheHttpClient/4.5.12(Java/11)
>>接受编码:gzip,deflate
>>“POST//oauth2/v2.0/token HTTP/1.1[\r][\n]”
>>“内容长度:840[\r][\n]”
>>“内容类型:application/x-www-form-urlencoded;charset=UTF-8[\r][\n]”
>>“主机:login.microsoftonline.com[\r][\n]”
>>“连接:保持活动状态[\r][\n]”
>>“用户代理:Apache HttpClient/4.5.12(Java/11)[\r][\n]”
>>接受编码:gzip,解压缩[\r][\n]
>>“[\r][\n]”
>>“客户机\u secret=GQflwHG…..m&grant\u type=authorization\u code&code=PAQAB…..客户机\u id=….范围=group.read.all+user.read”

用于请求访问令牌的授权代码错误,并且由于您使用的是身份验证代码流,因此还缺少重定向uri参数,请参阅


非常感谢您的回复。您知道从哪里获取授权码吗?或者它看起来如何/我如何识别它?我目前的访问码通常以Paqabaaaaa…开头,大约750个字符长。这似乎是我在安全上下文中可以找到的唯一代码。我唯一能找到的其他代码是find是idToken(OidcIdToken),通常以eyJ0eX…开头,大约1350个字符长,这似乎也不正确。此外,我实际上有一种印象,我使用的是代表流:spring重定向(角度)前端到microsoft,它再次验证并调用spring,这次使用spring安全上下文提供的验证cookie。我现在有一个经过验证的用户,并尝试从microsoft调用API(在显示为“中间层访问令牌请求”的页面上)@YvesV.嗨,我更新了我的答案,根据您提供的代码,您正在使用ath代码流。OBO流需要一个客户端和两个api端,您可以参考。也许我的设置不清楚?我有一个客户端服务器应用程序:angular frontend,spring boot backend。前端请求一个页面,由后端重定向到microsoft登录、登录和e redirect from MS设置了一个cookie。前端重做调用,这次使用sessionid,并由spring security进行身份验证。所有这些都有效,在我的rest服务中,我可以检索用户数据。我找到openid令牌并可以对其进行解码。但是,我从spring security上下文获得的accesstoken没有在jwt.MS上解析,并且是clea通过您的调用,我确实可以在浏览器中请求accesstoken,但我不知道如何将其集成到上述流程中。我的后端是否必须进行此调用???在以前的spring引导版本中,我可以从OAuth2AuthenticationDetails检索令牌(由SecurityContectHolder.getContext().getAuthentication()的getDetails检索),但在最新版本中,这现在是一个WebAuthenticationDetails对象,没有此信息。
>> POST /<tenant-idb/oauth2/v2.0/token HTTP/1.1
>> Content-Length: 840
>> Content-Type: application/x-www-form-urlencoded; charset=UTF-8
>> Host: login.microsoftonline.com
>> Connection: Keep-Alive
>> User-Agent: Apache-HttpClient/4.5.12 (Java/11)
>> Accept-Encoding: gzip,deflate
>> "POST /<tenant-id>/oauth2/v2.0/token HTTP/1.1[\r][\n]"
>> "Content-Length: 840[\r][\n]"
>> "Content-Type: application/x-www-form-urlencoded; charset=UTF-8[\r][\n]"
>> "Host: login.microsoftonline.com[\r][\n]"
>> "Connection: Keep-Alive[\r][\n]"
>> "User-Agent: Apache-HttpClient/4.5.12 (Java/11)[\r][\n]"
>> "Accept-Encoding: gzip,deflate[\r][\n]"
>> "[\r][\n]"
>> "client_secret=GQflwHG.....m&grant_type=authorization_code&code=PAQAB......&client_id=.....&scope=group.read.all+user.read"
<< "HTTP/1.1 400 Bad Request[\r][\n]"
<< "Cache-Control: no-store, no-cache[\r][\n]"
<< "Pragma: no-cache[\r][\n]"
<< "Content-Type: application/json; charset=utf-8[\r][\n]"
<< "Expires: -1[\r][\n]"
<< "Strict-Transport-Security: max-age=31536000; includeSubDomains[\r][\n]"
<< "X-Content-Type-Options: nosniff[\r][\n]"
<< "P3P: CP="DSP CUR OTPi IND OTRi ONL FIN"[\r][\n]"
<< "x-ms-request-id: f5f093c0-caba-4c0c-ba68-3ccd5b424c00[\r][\n]"
<< "x-ms-ests-server: 2.1.11021.14 - DUB1 ProdSlices[\r][\n]"
<< "Set-Cookie: fpc=Al-xwX2rJtFLqoSZskQjAWU; expires=Tue, 13-Oct-2020 22:50:23 GMT; path=/; secure; HttpOnly; SameSite=None[\r][\n]"
<< "Set-Cookie: x-ms-gateway-slice=prod; path=/; secure; samesite=none; httponly[\r][\n]"
<< "Set-Cookie: stsservicecookie=ests; path=/; secure; samesite=none; httponly[\r][\n]"
<< "Date: Sun, 13 Sep 2020 22:50:22 GMT[\r][\n]"
<< "Content-Length: 485[\r][\n]"
<< "[\r][\n]"
<< "{"error":"invalid_grant","error_description":"AADSTS9002313: Invalid request. Request is malformed or invalid.\r\nTrace ID: f5f093c0-caba-4c0c-ba68-3ccd5b424c00\r\nCorrelation ID: a174fae6-35ca-45ae-8a80-cc53c5d86119\r\nTimestamp: 2020-09-13 22:50:23Z","error_codes":[9002313],"timestamp":"2020-09-13 22:50:23Z","trace_id":"f5f093c0-caba-4c0c-ba68-3ccd5b424c00","correlation_id":"a174fae6-35ca-45ae-8a80-cc53c5d86119","error_uri":"https://login.microsoftonline.com/error?code=9002313"}"
<< HTTP/1.1 400 Bad Request
<< Cache-Control: no-store, no-cache
<< Pragma: no-cache
<< Content-Type: application/json; charset=utf-8
<< Expires: -1
<< Strict-Transport-Security: max-age=31536000; includeSubDomains
<< X-Content-Type-Options: nosniff
<< P3P: CP="DSP CUR OTPi IND OTRi ONL FIN"
<< x-ms-request-id: f5f093c0-caba-4c0c-ba68-3ccd5b424c00
<< x-ms-ests-server: 2.1.11021.14 - DUB1 ProdSlices
<< Set-Cookie: fpc=Al-xwX2rJtFLqoSZskQjAWU; expires=Tue, 13-Oct-2020 22:50:23 GMT; path=/; secure; HttpOnly; SameSite=None
<< Set-Cookie: x-ms-gateway-slice=prod; path=/; secure; samesite=none; httponly
<< Set-Cookie: stsservicecookie=ests; path=/; secure; samesite=none; httponly
<< Date: Sun, 13 Sep 2020 22:50:22 GMT
<< Content-Length: 485
@GetMapping("current")
 public UserTo getCurrentUserInformation() throws IOException {
  OAuth2AuthenticationToken auth = (OAuth2AuthenticationToken) SecurityContextHolder.getContext().getAuthentication();
  OAuth2AuthorizedClient client = clientService.loadAuthorizedClient(auth.getAuthorizedClientRegistrationId(), auth.getName());
  string authorizationCode = "<the authorization code>";


  try (CloseableHttpClient httpclient = HttpClients.createDefault()) {
    List<NameValuePair> form = new ArrayList<>();
    form.add(new BasicNameValuePair("client_secret", "<configured client-secret>"));
    form.add(new BasicNameValuePair("grant_type", "authorization_code"));
    form.add(new BasicNameValuePair("code", authorizationCode));
    form.add(new BasicNameValuePair("redirect_uri", "<configured redirect_uri>"));
    form.add(new BasicNameValuePair("client_id", "<configured client_id>"));
    form.add(new BasicNameValuePair("scope", "group.read.all user.read"));
    UrlEncodedFormEntity entity = new UrlEncodedFormEntity(form, Consts.UTF_8);
    .....
}
https://login.microsoftonline.com/{tenant id}/oauth2/v2.0/authorize?
client_id={{client id}
&response_type=code
&redirect_uri={your redirect_uri}
&response_mode=query
&scope=openid offline_access https://graph.microsoft.com/.default
&state=12345