You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SSO登录用户获取Access Token时Authorize接口返回HTML错误求助

问题说明

你需要获取Access Token访问应用API,已经通过Postman可以正常拿到,现在尝试用Java Rest Assured复现「先拿授权码、再用授权码换Access Token」的流程,但调用Authorize接口时始终返回text/html类型的错误响应,错误信息如下:

<!DOCTYPE html>
<html dir="ltr" class="" lang="en">
<head>
    <title>Sign in to your account</title>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=2.0, user-scalable=yes">
    <meta http-equiv="Pragma" content="no-cache">
    <meta http-equiv="Expires" content="-1">
    <link rel="preconnect" href="https://aadcdn.msauth.net" crossorigin>
<meta http-equiv="x-dns-prefetch-control" content="on">
<link rel="dns-prefetch" href="//aadcdn.msauth.net">
<link rel="dns-prefetch" href="//aadcdn.msftauth.net">

    <meta name="PageID" content="ConvergedError" />
    <meta name="SiteID" content="" />
    <meta name="ReqLC" content="1033" />
    <meta name="LocLC" content="en-US" />

        <meta name="referrer" content="origin" />


    <noscript>
        <meta http-equiv="Refresh" content="0; URL=" />
    </noscript>

    
    
<meta name="robots" content="none" />

<script type="text/javascript">//<![CDATA[
$Config={"strHeaderText":"Sign in","unsafe_strTopMessage":"Sorry, but we’re having trouble signing you in.","strMainMessage":"We received a bad request.","strAdditionalMessage":"","strServiceExceptionMessage":"AADSTS900144: The request body must contain the following parameter: \u0026#39;scope\u0026#39;.","strTraceId":"43b3c9f3-5d82-43e1-ae7e-fcb88fe24d00","iErrorCode":900144,"iHttpErrorCode":400,"iViewId":1,"urlCancel":"","strTimestamp":"2021-08-23T18:09:43Z","urlLearnMoreRiskyApp":"https://go.microsoft.com/fwlink/?linkid=2133457","iMaxStackForKnockoutAsyncComponents":10000,"fShowButtons":true,"fEnabledFlaggedSigninFlow":true,"urlCdn":"https://aadcdn.msauth.net/shared/1.0/","urlFooterTOU":"https://www.microsoft.com/en-US/servicesagreement/","urlFooterPrivacy":"https://privacy.microsoft.com/en-US/privacystatement","iPawnIcon":0,"sPOST_Username":"","sFTName":"flowToken","dynamicTenantBranding":null,"staticTenantBranding":null,"fEnableLayoutTemplates":true,"oAppCobranding":{},"iBackgroundImage":2,"fApplicationInsightsEnabled":false,"iApplicationInsightsEnabledPercentage":0,"urlSetDebugMode":"https://login.microsoftonline.com/common/debugmode","fEnableCssAnimation":true,"fAllowGrayOutLightBox":true,"fIsRemoteNGCSupported":true,"fUseSameSite":true,"uiflavor":1001,"fOfflineAccountVisible":false,"scid":1013,"hpgact":1800,"hpgid":1117,"pgid":"ConvergedError","apiCanary":"AQABAAAAAAD--DLA3VO7QrddgJg7Wevr4vgU5dSyj56ii8l46ni2Rlv-gbTV2fIzqJIZnmVvo36GN53V3xSnHh5tMvCuWoooKdZMo9EdfVDONwnh2GgbIDGAN_B1AjGh8Hp1P5BuOwdAgdkHrcxUmzKCivfO5qKbuG8mEyfK7w0wOcdk33wnPqkZU-N_Kh6GBxCHFt_5VMVU4LGhfBi9z9FKR9khgg94FHH3ozYq6Io8vIR1sDHjgyAA","canary":"/5Mr0VLUDgJZmi+BudaCdz5N6AwqT1rk13F4BqW281Y=8:1","correlationId":"103f8f0c-3657-447d-ba14-b899e94fa7aa","sessionId":"43b3c9f3-5d82-43e1-ae7e-fcb88fe24d00","locale":{"mkt":"en-US","lcid":1033},"slMaxRetry":2,"slReportFailure":true,"strings":{"desktopsso":{"authenticatingmessage":"Trying to sign you in"}},"enums":{"ClientMetricsModes":{"None":0,"SubmitOnPost":1,"SubmitOnRedirect":2,"InstrumentPlt":4}},"urls":{"instr":{"pageload":"https://login.microsoftonline.com/common/instrumentation/reportpageload","dssostatus":"https://login.microsoftonline.com/common/instrumentation/dssostatus"}},"browser":{"ltr":1,"_Other":1,"Full":1,"RE_Other":1,"b":{"name":"Other","major":-1,"minor":-1},"os":{"name":"Unknown","version":""},"V":-1},"watson":{"url":"/common/handlers/watson","bundle":"https://aadcdn.msauth.net/ests/2.1/content/cdnbundles/watson.min_ybdb1ixzkv-fkor2mu6q6w2.js","sbundle":"https://aadcdn.msauth.net/ests/2.1/content/cdnbundles/watsonsupportwithjquery.3.5.min_dc940oomzau4rsu8qesnvg2.js","fbundle":"https://aadcdn.msauth.net/ests/2.1/content/cdnbundles/frameworksupport.min_oadrnc13magb009k4d20lg2.js","resetErrorPeriod":5,"maxCorsErrors":-1,"maxInjectErrors":5,"maxErrors":10,"maxTotalErrors":3,"expSrcs":["https://login.microsoftonline.com","https://aadcdn.msauth.net/","https://aadcdn.msftauth.net/",".login.microsoftonline.com"],"envErrorRedirect":true,"envErrorUrl":"/common/handlers/enverror"},"loader":{"cdnRoots":["https://aadcdn.msauth.net/","https://aadcdn.msftauth.net/"],"logByThrowing":true},"serverDetails":{"slc":"ProdSlices","dc":"SEASLR1","ri":"SI2XXXX","ver":{"v":[2,1,11935,14]},"rt":"2021-08-23T18:09:43","et":0},"clientEvents":{"enabled":true,"telemetryEnabled":true,"useOneDSEventApi":true,"flush":60000,"autoPost":true,"autoPostDelay":1000,"minEvents":1,"maxEvents":1,"pltDelay":500,"appInsightsConfig":{"instrumentationKey":"69adc3c768bd4dc08c19416121249fcc-66f1668a-797b-4249-95e3-6c6651768c28-7293","webAnalyticsConfiguration":{"autoCapture":{"jsError":true}}},"defaultEventName":"IDUX_ESTSClientTelemetryEvent_WebWatson","serviceID":3},"fApplyAsciiRegexOnInput":true,"fBreakBrandingSigninString":true,"fFixIncorrectApiCanaryUsage":true,"fTrimChromeBssoUrl":true,"inlineMode":5};
//]]></script>
</head>
</html>

你编写的获取授权码的代码如下:

oAuthToken = given()
        .header("authorization", "Basic " + <encoded username and password>)
        .contentType(ContentType.URLENC)
        .formParam("response_type", "code")
        .queryParam("client_id", "<xyz client id>")
        .queryParam("redirect_uri", "<the call back url>")
        .queryParam("scope", "user.read")
        .post("/oauth2/v2.0/authorize")
        .then()
        .statusCode(200)
        .extract()
        .response();

你当前使用的可正常运行的Postman配置如下:
Postman Setting for Access Code

问题分析与解决方案

首先从错误提示AADSTS900144: The request body must contain the following parameter: 'scope'可以直接定位第一个错误:

  • 你设置了请求的content-type为application/x-www-form-urlencoded,但将client_id、redirect_uri、scope三个参数放在了查询参数(queryParam)中,服务端会从POST请求的表单体中读取参数,自然找不到必填的scope字段,直接报错。

其次你对OAuth2授权码流的响应逻辑理解有误:

  • 授权码流的Authorize接口请求成功后,不会返回包含授权码的JSON响应,而是返回302重定向响应,授权码会附加在你配置的redirect_uri的查询参数中,你当前校验响应状态码为200,本身就是错误的逻辑。
  • Postman能正常拿到token,是因为Postman内置的OAuth2授权功能自动处理了登录跳转、重定向拦截提取授权码、调用token接口换token的全流程,不是直接调用Authorize接口就能拿到授权码。

如果是自动化测试场景不需要用户交互,更推荐直接使用密码流或者客户端凭据流,跳过拿授权码的步骤,直接调用/oauth2/v2.0/token接口拿token,适配性更高。

修正后的Authorize请求示例代码如下:

Response authResponse = given()
        .contentType(ContentType.URLENC)
        // 所有参数都放在formParam中,不要用queryParam
        .formParam("response_type", "code")
        .formParam("client_id", "<xyz client id>")
        .formParam("redirect_uri", "<the call back url>")
        .formParam("scope", "user.read")
        // 如果需要免登录,补充用户名密码参数
        .formParam("username", "<your username>")
        .formParam("password", "<your password>")
        // 不要拦截重定向,方便拿到重定向地址
        .redirects().follow(false)
        .post("/oauth2/v2.0/authorize")
        .then()
        // 成功响应是302不是200
        .statusCode(302)
        .extract()
        .response();

// 从重定向地址中提取授权码
String redirectUrl = authResponse.getHeader("Location");
String authCode = redirectUrl.split("code=")[1].split("&")[0];

内容的提问来源于stack exchange,提问作者Bhuvaneshwari K

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.06 23:51:04