尝试从 Azure AD 获取访问令牌时获取响应代码 400
Posted
技术标签:
【中文标题】尝试从 Azure AD 获取访问令牌时获取响应代码 400【英文标题】:Getting response code 400 when trying to get access token from Azure AD 【发布时间】:2018-06-04 23:32:14 【问题描述】:我正在为我的 Web 应用程序实现 azure,并尝试按照 openId 连接教程获取访问令牌
https://docs.microsoft.com/en-us/azure/active-directory/develop/active-directory-protocols-oauth-code
当我请求获取访问令牌时,我总是收到错误的请求 400
请求获取访问令牌:
POST /租户/oauth2/token HTTP/1.1
主持人:https://login.microsoftonline.com
内容类型:application/x-www-form-urlencoded
grant_type=authorization_code
&client_id=2d4d11a2-f814-46a7-890a-274a72a7309e
&code=AwABAAAAvPM1KaPl.......
&redirect_uri=https%3A%2F%2Flocalhost%2Fmyapp%2F
&resource=https%3A%2F%2Fservice.contoso.com%2F
&client_secret=p@ssw0rd
这是我的代码:
public static String post( String endpoint,
Map<String, String> params) //YD
StringBuffer paramString = new StringBuffer("");
//if(!Utilities.checkInternetConnection(context))
// return XMLHandler.getXMLForErrorCode(context, JSONHandler.ERROR_CODE_INTERNET_CONNECTION);
//
Iterator<Entry<String, String>> iterator = params.entrySet().iterator();
StringBuffer tempBuffer = new StringBuffer("");
String paramval;
while (iterator.hasNext())
Entry<String, String> param = iterator.next();
if (param != null)
if (paramString.length() > 0)
paramString.append("&");
System.out.println( "post key : " + param.getKey());
String value;
try
paramval = param.getValue();
if(paramval!=null)
value = URLEncoder.encode(paramval, "UTF-8");
else
value = "";
catch (UnsupportedEncodingException e)
value = "";
e.printStackTrace();
paramString.append(param.getKey()).append("=")
.append(value);
try
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost(endpoint);
String data = "";
try
// Add your data
// httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs))
//httppost.addHeader("Host", host);
httppost.addHeader("Content-Type",
"application/x-www-form-urlencoded");
if (!paramString.equals(""))
if (tempBuffer.length() > 0)
data = data + tempBuffer.toString();
data = data + paramString.toString();
if (data.endsWith("&"))
data = data.substring(0, data.length() - 1);
httppost.setEntity(new ByteArrayEntity(data.getBytes()));
System.out.println( "post Stringbuffer : " + data);
// Execute HTTP Post Request
HttpResponse response = httpclient.execute(httppost);
int statuscode = response.getStatusLine().getStatusCode();
System.out.println("Response code : " + statuscode);
if (statuscode != 200)
return null;
HttpEntity entity = response.getEntity();
InputStream in = null;
if (entity != null)
in = entity.getContent();
if (in != null)
StringBuilder builder = new StringBuilder();
String line;
try
BufferedReader reader = new BufferedReader(
new InputStreamReader(in, "UTF-8"));
while ((line = reader.readLine()) != null)
builder.append(line);
finally
in.close();
String response2 = builder.toString();
System.out.println("response :" + response2);
retrycount = 0;
return response2;
catch(UnknownHostException e)
e.printStackTrace();
return null;
catch (EOFException eof)
if (retrycount < max_retry)
eof.printStackTrace();
post( endpoint, params);
retrycount = 1;
catch (Throwable th)
throw new IOException("Error in posting :" + th.getMessage());
retrycount = 0;
return null;
catch (Exception e)
e.printStackTrace();
return null;
请帮帮我
提前致谢
【问题讨论】:
客户端的秘密就一定是为应用程序制作的密钥吗?它还需要进行 URL 编码。 【参考方案1】:请参考下方代码申请AuthorizationCode
。
public static void getAuthorizationCode() throws IOException
String encoding = "UTF-8";
String params = "client_id=" + clientId
+ "&response_type=" + reponseType
+ "&redirect_uri=http%3A%2F%2Flocalhost%2Fmyapp%2F"
+ "&response_mode=query"
+ "&resource=https%3A%2F%2Fgraph.windows.net"
+ "&state=12345";
String path = "https://login.microsoftonline.com/" + tenantId + "/oauth2/authorize";
byte[] data = params.getBytes(encoding);
URL url = new URL(path);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("POST");
conn.setDoOutput(true);
conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
conn.setRequestProperty("Content-Length", String.valueOf(data.length));
conn.setConnectTimeout(5 * 1000);
OutputStream outStream = conn.getOutputStream();
outStream.write(data);
outStream.flush();
outStream.close();
System.out.println(conn.getResponseCode());
System.out.println(conn.getResponseMessage());
BufferedReader br = null;
if (conn.getResponseCode() != 200)
br = new BufferedReader(new InputStreamReader((conn.getErrorStream())));
else
br = new BufferedReader(new InputStreamReader((conn.getInputStream())));
System.out.println("Response body : " + br.readLine());
然后您可以使用您获得的AuthorizationCode
获取access token
,并使用以下代码获取刷新代码。
public static void getToken(String refreshToken) throws IOException
String encoding = "UTF-8";
String params = "client_id=" + clientId + "&refresh_token=" + refreshToken
+ "&grant_type=refresh_token&resource=https%3A%2F%2Fgraph.windows.net";
String path = "https://login.microsoftonline.com/" + tenantId + "/oauth2/token";
byte[] data = params.getBytes(encoding);
URL url = new URL(path);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("POST");
conn.setDoOutput(true);
conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
conn.setRequestProperty("Content-Length", String.valueOf(data.length));
conn.setConnectTimeout(5 * 1000);
OutputStream outStream = conn.getOutputStream();
outStream.write(data);
outStream.flush();
outStream.close();
System.out.println(conn.getResponseCode());
System.out.println(conn.getResponseMessage());
BufferedReader br = null;
if (conn.getResponseCode() != 200)
br = new BufferedReader(new InputStreamReader((conn.getErrorStream())));
else
br = new BufferedReader(new InputStreamReader((conn.getInputStream())));
System.out.println("Response body : " + br.readLine());
希望对你有帮助。
【讨论】:
【参考方案2】:您是否确保传递给 /token 的重定向 uri 与传递给 /authorize 的重定向 uri 相同
我相信,如果您可以使用 Postman 工具使用当前客户端 ID、机密和范围测试 OAuth 身份验证代码流以排除错误配置,这将有所帮助。
【讨论】:
以上是关于尝试从 Azure AD 获取访问令牌时获取响应代码 400的主要内容,如果未能解决你的问题,请参考以下文章
使用 JWT 令牌保护 asp.net 核心 Web api 时如何从 Azure AD 获取用户
在 Postman 中为 Azure AD B2C 请求访问令牌