Oauth 2.0 使用内部ADF登录azure oauth2

Oauth 2.0 使用内部ADF登录azure oauth2,oauth-2.0,azure-active-directory,adfs,Oauth 2.0,Azure Active Directory,Adfs,我正试图在一些python脚本中使用oauth2连接到我们的azure租户。我创建了一个应用程序注册,并允许对其进行一些API访问 当我尝试使用用户名和密码连接时,我只会得到一个错误代码50126(无效的用户名或密码) 如果我在我的应用注册中定义了一些秘密,并将客户端秘密切换为grant_类型,我将有权访问我的应用 但我想使用用户名和密码。用户名是user@domain.com密码也正确 所以我认为我们的ADFS服务器出现了问题 我们正在使用一些本地广告,并将用户数据与azure Connect

我正试图在一些python脚本中使用oauth2连接到我们的azure租户。我创建了一个应用程序注册,并允许对其进行一些API访问

当我尝试使用用户名和密码连接时,我只会得到一个
错误代码50126
(无效的用户名或密码)

如果我在我的应用注册中定义了一些秘密,并将客户端秘密切换为grant_类型,我将有权访问我的应用

但我想使用用户名和密码。用户名是
user@domain.com
密码也正确

所以我认为我们的ADFS服务器出现了问题

我们正在使用一些本地广告,并将用户数据与azure Connect同步到azure,但我们不同步密码。因此,Azure的登录被转发到我们的adfs实例,并在本地完成

如何在脚本中实现该逻辑?我需要像重定向到adfs这样的东西,使用我的用户名和密码,并且需要正确的响应才能登录azure

我已经为此搜索了很多,但没有找到答案。我无法激活密码同步

我与azure的连接参数如下

tokenpost = {
    'client_id':clientid,
    'resource':crmorg,
    'password':password,
    'username':'user@domain.com',
    'grant_type':'password'
}
tokenres = requests.post('https://login.microsoftonline.com/<tenantid>/oauth2/token', data=tokenpost)
tokenpost={
“客户端id”:客户端id,
“资源”:crmorg,
“密码”:密码,
“用户名”:”user@domain.com',
“授权类型”:“密码”
}
tokenres=requests.post('https://login.microsoftonline.com//oauth2/token,data=tokenpost)
有些人也有同样的问题

最好的, 罗宾明白了。 首先需要从ADFS获取断言。 这就是给我很大帮助的医生:

我现在是用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];
  }
}
包Azure
导入org.apache.commons.httpclient.HostConfiguration;
导入org.apache.commons.httpclient.httpclient;
导入org.apache.commons.httpclient.methods.PostMethod;
导入java.util.Base64;
字符串getAzureAccessToken(字符串clientId、字符串断言、字符串azureURL)
{
HttpClient HttpClient=新HttpClient();
PostMethod methodPost=新的PostMethod(azureURL);
methodPost.setRequestHeader(“内容类型”、“应用程序/x-www-form-urlencoded”);
methodPost.setRequestHeader(“主机”,“登录名.microsoftonline.com”);
addParameter(“grant_类型”,“urn:ietf:params:oauth:grant类型:saml2承载”);
addParameter(“断言”,Base64.getEncoder().encodeToString(assertion.getBytes());
methodPost.addParameter(“客户机密”、“XXX”);
addParameter(“客户端id”,clientId);
methodPost.addParameter(“范围”、“XXX”);
addParameter(“接受”、“应用程序/json”);
int returnCode=httpClient.executeMethod(methodPost)
如果(返回代码!=200)
{
抛出新异常(“无法连接到Azure”+methodPost.getStatusLine().toString())
}
BufferedReader br=新的BufferedReader(新的InputStreamReader(methodPost.getResponseBodyAsStream());
字符串响应;
而((response=br.readLine())!=null){
返回响应。拆分(“\”访问令牌\“:\”)[1]。拆分(“\”)[0];
}
}
String getAdfsAssertion(字符串用户名、字符串密码、字符串adfsURL)
{
字符串adfsSoapXML=“”
http://docs.oasis-open.org/ws-sx/ws-trust/200512/RST/Issue
urn:uuid:XXX
http://www.w3.org/2005/08/addressing/anonymous
“+adfsURL+”
“+username+”
“+密码+”
urn:federation:MicrosoftOnline
http://docs.oasis-open.org/ws-sx/ws-trust/200512/Bearer
http://docs.oasis-open.org/ws-sx/ws-trust/200512/Issue
urn:oasis:names:tc:SAML:2.0:assertion
""";
HttpClient HttpClient=新HttpClient();
PostMethod methodPost=新的PostMethod(adfsURL);
setRequestBody(adfsSoapXML);
setRequestHeader(“SOAPAction”http://docs.oasis-open.org/ws-sx/ws-trust/200512/RST/Issue");
setRequestHeader(“内容类型”、“应用程序/soap+xml”);
methodPost.setRequestHeader(“客户端请求id”、“XXX”);
setRequestHeader(“返回客户端请求id”、“true”);
setRequestHeader(“接受”、“应用程序/json”);
int returnCode=httpClient.executeMethod(methodPost)
如果(返回代码!=200)
{
抛出新异常(“无法连接到adfs”+methodPost.getStatusLine().toString())
}
BufferedReader br=新的BufferedReader(新的InputStreamReader(methodPost.getResponseBodyAsStream());
字符串响应;
而((response=br.readLine())!=null){
返回响应。拆分(“”[1]。拆分(“”[0];
}
}

我在最近一个问题中的回答可能会有所帮助: