Search code examples
azureazure-active-directoryazure-service-principalazure-python-sdk

Create Azure service principal using python SDK


Is there currently any way to create a service principal using python SDK in azure?

I have tried doing it with azure-graphrbac but it currently is deprecated and it fails to load DefaultAzureCredential from azure-identity. I have tried creating the wrapper and using it as well but it fails while loading session token.

CredentialsWrapper.py

from azure.identity import DefaultAzureCredential
from msrest.authentication import BasicTokenAuthentication
from azure.core.pipeline.policies import BearerTokenCredentialPolicy
from azure.core.pipeline import PipelineRequest, PipelineContext
from azure.core.pipeline.transport import HttpRequest

class CredentialWrapper(BasicTokenAuthentication):
    def __init__(self, credential=None, resource_id="https://graph.microsoft.com/.default", **kwargs):
        super(CredentialWrapper, self).__init__(None)
        if credential is None:
            credential = DefaultAzureCredential()
        self._policy = BearerTokenCredentialPolicy(credential, resource_id, **kwargs)

    def _make_request(self):
        return PipelineRequest(
            HttpRequest(
                "CredentialWrapper",
                "https://fakeurl"
            ),
            PipelineContext(None)
        )

    def set_token(self):
        request = self._make_request()
        self._policy.on_request(request)
        print(request.http_request.headers["Authorization"])
        token = request.http_request.headers["Authorization"]
        self.token = {"access_token": token}

    def signed_session(self, session=None):
        self.set_token()
        return super(CredentialWrapper, self).signed_session(session)

Solution

  • To create the Service Principal using DefaultAzureCredential from azure-identity, make use of below code:

    import requests
    from azure.identity import DefaultAzureCredential
    
    class TokenGenerator:
        def generate_token(self):
            try:
                credential = DefaultAzureCredential()
                token = credential.get_token("https://graph.microsoft.com/.default")
                return token.token
            except Exception as ex:
                # Handle any exceptions
                print(f"An error occurred: {ex}")
                return None
    
    generator = TokenGenerator()
    access_token = generator.generate_token()
    
    if access_token:
       
        headers = {
            "Authorization": f"Bearer {access_token}",
            "Content-Type": "application/json"
        }
    
        
        payload = {
            "appId": "MicrosoftEntraApplicationAppID"
        }
    
        response = requests.post("https://graph.microsoft.com/v1.0/servicePrincipals", headers=headers, json=payload)
    
        if response.status_code == 201:
            print("Service principal created successfully.")
        else:
            print(f"Failed to create service principal. Status code: {response.status_code}")
    else:
        print("Failed to obtain access token.")
    

    enter image description here

    The service principal got created successfully:

    enter image description here