Azure AD OAuth隐式流使用token响应类型时的回调参数获取问题
哈哈,这个问题我之前帮好几个开发者解决过!这其实是OAuth 2.0隐式授权流的标准行为,不是Azure AD的bug哦~
为什么会出现#而不是??
OAuth 2.0隐式流的设计初衷就是把access_token放在URL的片段部分(#后面的内容),而非查询参数(?后面)。这么做是为了安全:片段信息只会保留在浏览器端,不会被发送到服务器,能避免令牌被写入服务器日志、代理日志等地方,降低泄露风险。而你用的Request.Params.Get("access_token")是从服务器收到的请求参数里拿值,自然取不到浏览器端才有的片段内容。
怎么获取到这个access_token?
根据你的应用架构,有两种常见的解决方式:
方法1:前端直接提取(推荐,符合隐式流设计)
因为片段只有浏览器能访问,用JavaScript就能轻松提取:
// 截取#后面的部分,去掉开头的# const hashContent = window.location.hash.slice(1); // 把片段内容转换成键值对对象 const tokenParams = new URLSearchParams(hashContent); // 获取access_token const accessToken = tokenParams.get('access_token'); // 之后你可以用这个令牌做前端请求,或者传给后端(比如放在请求Header里)
方法2:通过前端中转给后端(如果必须后端处理)
如果你的业务逻辑必须在后端拿到令牌,可以通过前端做一次中转:
- 第一步:用上面的前端代码提取
access_token - 第二步:通过POST请求(推荐,避免令牌出现在URL里)或者安全的方式把令牌传给后端接口
- 第三步:后端从请求体或者自定义的请求Header中获取令牌
额外建议
如果你的应用是服务器端渲染(比如ASP.NET、Java Web这类),其实更推荐使用授权码流(把response_type设为code)。这种方式下,Azure AD会返回授权码到后端,再由后端去交换令牌,全程令牌不会经过前端,安全性更高,也不会有URL片段的问题。
内容的提问来源于stack exchange,提问作者It's a trap
相关产品推荐
相关产品推荐

