Forum Discussion

FilipSevcik's avatar
FilipSevcik
Regular Visitor
1 year ago
Solved

Custom PBi connector for MS Graph

Hi community, i am trying to build custom connector for PBI in VS Code using Power Query SDK, but struggling to get it discoverable for pbi desktop while getting data; i have sample downloaded form ...
  • DataNinja777's avatar
    1 year ago

    Hi FilipSevcik ,

     

    It's a common hurdle to get a custom connector to appear in Power BI Desktop for the first time. Since you've confirmed that a sample connector from GitHub is working, we can be confident that your Power BI settings and folder path are correct. This suggests the issue is within the code or the structure of your .mez file.

    The most likely reason your connector isn't being discovered by Power BI is related to how you've defined the button text. Your code uses the Extension.LoadString function, which instructs Power BI to load text from a resources.resx file within your project. If this resource file is missing or doesn't contain the specified keys ("ButtonTitle", "ButtonHelp"), the connector metadata cannot be parsed correctly, and Power BI will silently ignore it.

    Your current publishing code looks like this:

    MSGraphAPIConnector.Publish = [
        Beta = true,
        Category = "Other",
        ButtonText = { Extension.LoadString("ButtonTitle"), Extension.LoadString("ButtonHelp") },
        LearnMoreUrl = "https://powerbi.microsoft.com/",
        SourceImage = MSGraphAPIConnector.Icons,
        SourceTypeImage = MSGraphAPIConnector.Icons
    ];

    To quickly test if this is the cause, you can temporarily replace the Extension.LoadString calls with hardcoded text. After making this change, rebuild the .mez file and restart Power BI Desktop. The connector should now become visible in the "Get Data" dialog.

    MSGraphAPIConnector.Publish = [
        Beta = true,
        Category = "Other",
        ButtonText = { "MS Graph API Connector", "Connect to Microsoft Graph API" },
        LearnMoreUrl = "https://powerbi.microsoft.com/",
        SourceImage = MSGraphAPIConnector.Icons,
        SourceTypeImage = MSGraphAPIConnector.Icons
    ];

    While that should solve the discovery issue, there is a more fundamental architectural problem with the connector's authentication method. Hardcoding the client_id, client_secret, and tenantId is a significant security risk, as the secret is stored in plain text. Furthermore, this design will cause practical issues. The access token will expire, typically in an hour, causing any manual or scheduled refreshes to fail because your code does not handle token renewal. The proper, secure, and robust solution is to leverage Power Query's built-in authentication handlers.

    For the Microsoft Graph API, you should use the Aad (Azure Active Directory) authentication kind. This allows the Power Query framework to manage the entire OAuth 2.0 sign-in process, including securely storing credentials and automatically refreshing tokens. A refactored and much-improved version of your connector would use OData.Feed, which is optimized for OData services like the Graph API, and would define the Aad authentication type. This eliminates all manual token handling and hardcoded secrets.

    [Version = "1.0.0"]
    section MSGraphAPIConnector;
    
    [DataSource.Kind="MSGraphAPIConnector", Publish="MSGraphAPIConnector.Publish"]
    shared MSGraphAPIConnector.Contents = () =>
        let
            source = OData.Feed("https://graph.microsoft.com/v1.0", null, [
                Implementation = "2.0"
            ])
        in
            source;
    
    MSGraphAPIConnector = [
        Authentication = [
            Aad = [
                AuthorizationUri = "https://login.microsoftonline.com/common/oauth2/v2.0/authorize",
                Resource = "https://graph.microsoft.com"
            ]
        ],
        Label = "MS Graph API Connector (Recommended)"
    ];
    
    MSGraphAPIConnector.Publish = [
        Beta = true,
        Category = "Other",
        ButtonText = { "MS Graph API Connector (Recommended)", "Connect to Microsoft Graph API" },
        LearnMoreUrl = "https://powerbi.microsoft.com/",
        SourceImage = MSGraphAPIConnector.Icons,
        SourceTypeImage = MSGraphAPIConnector.Icons
    ];
    
    MSGraphAPIConnector.Icons = [
        Icon16 = { Extension.Contents("MSGraph16.png"), Extension.Contents("MSGraph20.png"), Extension.Contents("MSGraph24.png"), Extension.Contents("MSGraph32.png") },
        Icon32 = { Extension.Contents("MSGraph32.png"), Extension.Contents("MSGraph40.png"), Extension.Contents("MSGraph48.png"), Extension.Contents("MSGraph64.png") }
    ];

    By implementing this revised code, you gain significant advantages. The OData.Feed function will automatically handle pagination (@odata.nextLink) and schema detection. The Authentication section tells Power BI to use a standard Microsoft sign-in prompt, and the framework will pass the necessary authorization token to the Graph API on every call. To make this work, you must update your app registration in the Azure portal. Under the "Authentication" section, add a platform for "Mobile and desktop applications" and set the redirect URI to https://oauth.powerbi.com/views/oauthredirect.html. Also, ensure you have configured the necessary delegated API permissions (like User.Read.All), as the user will be signing in and consenting on their own behalf. This approach results in a secure, robust, and shareable connector that functions correctly in both Power BI Desktop and the Power BI Service.

     

    Best regards,

  • V-yubandi-msft's avatar
    1 year ago

    Hi FilipSevcik ,

    Thank you for engaging with the Microsoft Fabric Community.

    Error:

    AADSTS9002326: The 'resource' request parameter is not supported

    This means they are using the OAuth v2.0 endpoint with a resource parameter which is not allowed. The correct fix is to replace resource  with scope, as you correctly stated.

     

    Regards,
    Yugandhar.