我正在尝试将oauth2与某些python脚本中的azure租户连接。我创建了一个应用注册,并允许一些API访问。
当我尝试使用用户名和密码进行连接时,我只会得到Error Code 50126
(无效的用户名或密码)。
[如果我在应用程序注册中定义了一些机密,并切换为client secret作为grant_type,则可以访问我的应用程序。
但是我想使用用户名和密码。用户名是[email protected]
,密码也是正确的。
所以我认为我们的ADFS服务器出现问题。
我们正在使用一些本地AD,并将用户数据同步到Azure Connect,但是我们不同步密码。因此,登录到Azure的请求将转发到我们的adfs实例,并在前提下完成。
如何在脚本中实现该逻辑?我需要使用用户名和密码重定向到adfs的东西,并且需要正确的登录响应才能使天青。
我已经为此进行了很多搜索,但没有找到答案。我无法激活密码同步。
我的天蓝色连接参数就像
tokenpost = {
'client_id':clientid,
'resource':crmorg,
'password':password,
'username':'[email protected]',
'grant_type':'password'
}
tokenres = requests.post('https://login.microsoftonline.com/<tenantid>/oauth2/token', data=tokenpost)
有些人遇到同样的问题?
最好,罗宾
知道了。必须首先从ADFS中获得一个断言。这是对我有很大帮助的文档:https://docs.microsoft.com/en-us/azure/active-directory/develop/v2-saml-bearer-assertion
我现在用Java写的,但是在python中应该非常相等:
package Azure
import org.apache.commons.httpclient.HostConfiguration;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.methods.PostMethod;
import java.util.Base64;
String getAzureAccessToken(String clientId, String assertion, String azureURL)
{
HttpClient httpClient = new HttpClient();
PostMethod methodPost = new PostMethod(azureURL);
methodPost.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
methodPost.setRequestHeader("Host", "login.microsoftonline.com");
methodPost.addParameter("grant_type", "urn:ietf:params:oauth:grant-type:saml2-bearer");
methodPost.addParameter("assertion", Base64.getEncoder().encodeToString(assertion.getBytes()));
methodPost.addParameter("client_secret", "XXX");
methodPost.addParameter("client_id", clientId);
methodPost.addParameter("scope", "XXX");
methodPost.addParameter("Accept", "application/json");
int returnCode = httpClient.executeMethod(methodPost)
if(returnCode != 200)
{
throw new Exception("Cannot connect to Azure "+methodPost.getStatusLine().toString())
}
BufferedReader br = new BufferedReader(new InputStreamReader(methodPost.getResponseBodyAsStream()));
String response;
while ((response = br.readLine()) != null) {
return response.split("\"access_token\":\"")[1].split("\"")[0];
}
}
String getAdfsAssertion(String username, String password, String adfsURL)
{
String adfsSoapXML = """<?xml version="1.0" encoding="utf-8"?>
<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope"
xmlns:a="http://www.w3.org/2005/08/addressing"
xmlns:u="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
<s:Header><a:Action s:mustUnderstand="1">http://docs.oasis-open.org/ws-sx/ws-trust/200512/RST/Issue</a:Action>
<a:MessageID>urn:uuid:XXX</a:MessageID>
<a:ReplyTo><a:Address>http://www.w3.org/2005/08/addressing/anonymous</a:Address></a:ReplyTo>
<a:To s:mustUnderstand="1">"""+ adfsURL +"""</a:To>
<o:Security s:mustUnderstand="1" xmlns:o="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" >
<o:UsernameToken u:Id="XXX">
<o:Username>"""+ username +"""</o:Username>
<o:Password>"""+ password +"""</o:Password>
</o:UsernameToken>
</o:Security>
</s:Header>
<s:Body>
<trust:RequestSecurityToken xmlns:trust="http://docs.oasis-open.org/ws-sx/ws-trust/200512">
<wsp:AppliesTo xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy">
<a:EndpointReference>
<a:Address>urn:federation:MicrosoftOnline</a:Address>
</a:EndpointReference>
</wsp:AppliesTo>
<trust:KeyType>http://docs.oasis-open.org/ws-sx/ws-trust/200512/Bearer</trust:KeyType>
<trust:RequestType>http://docs.oasis-open.org/ws-sx/ws-trust/200512/Issue</trust:RequestType>
<trust:TokenType>urn:oasis:names:tc:SAML:2.0:assertion</trust:TokenType>
</trust:RequestSecurityToken>
</s:Body>
</s:Envelope>
""";
HttpClient httpClient = new HttpClient();
PostMethod methodPost = new PostMethod(adfsURL);
methodPost.setRequestBody(adfsSoapXML);
methodPost.setRequestHeader("SOAPAction", "http://docs.oasis-open.org/ws-sx/ws-trust/200512/RST/Issue");
methodPost.setRequestHeader("Content-type", "application/soap+xml");
methodPost.setRequestHeader("client-request-id", "XXX");
methodPost.setRequestHeader("return-client-request-id", "true");
methodPost.setRequestHeader("Accept", "application/json");
int returnCode = httpClient.executeMethod(methodPost)
if(returnCode != 200)
{
throw new Exception("Cannot connect to adfs "+methodPost.getStatusLine().toString())
}
BufferedReader br = new BufferedReader(new InputStreamReader(methodPost.getResponseBodyAsStream()));
String response;
while ((response = br.readLine()) != null) {
return response.split("<trust:RequestedSecurityToken>")[1].split("</trust:RequestedSecurityToken>")[0];
}
}