Authenticate my own Blazor App with against my SSO-REST Backend

Clemens Mattner 20 Reputation points
2024-09-13T08:27:44.94+00:00

Hi,

regarding to this blog https://devblogs.microsoft.com/dotnet/whats-new-with-identity-in-dotnet-8/

I've successfully created a REST-API with Identity and SSO.

But now I need my Blazor frontend to authenticate against this rest service. The blog describes how to authenticate against Google, facebook, etc...

but I don't get the point. How do I authenticate my own application against my own REST-API if I want to have SSO on both sides?

Everything should work with our SSO (AzureAD)

Blazor
Blazor
A free and open-source web framework that enables developers to create web apps using C# and HTML being developed by Microsoft.
1,604 questions
ASP.NET API
ASP.NET API
ASP.NET: A set of technologies in the .NET Framework for building web applications and XML web services.API: A software intermediary that allows two applications to interact with each other.
346 questions
0 comments No comments
{count} votes

Accepted answer
  1. Tiny Wang-MSFT 2,816 Reputation points Microsoft Vendor
    2024-09-16T06:49:23.9066667+00:00

    Hi @Clemens Mattner, per my understanding, REST-API should be able to provide endpoints for authentication, but itself doesn't have identity feature. Because API project should not have a UI for users to enter their account and password, so that I'm not very sure about what do you mean for created a REST-API with Identity and SSO. But we could obviously to see that you are working on a blazor web assembly frontend app and this app is required to connect to Web Api secured by Azure AD. Azure AD provide SSO features for frontend, but when the frontend app is going to call API, it still requires to add Access Token in request header to bypass the authorization. SSO doesn't help in this scenario. Please allow me to share you a simple sample here for better understanding.

    Firstly, let's have a Web Api project integrating Azure AD for authorization. We can create a new project using VS template, and let's select Microsoft Identity Platform as the Authentication Type.

    User's image

    Then we need to modify the appsettings.json file to fill the configurations for Azure AD. It shall look like below. The Scopes field requires us to expose an api permission in Azure AD, you might follow the tutorial I shared above to create Azure AD application, add client secret and exposing API. The Azure AD application used for the API project can be used in the blazor Wasm application at the same time.

    "AzureAd": {
      "Instance": "https://login.microsoftonline.com/",
      "Domain": "tenant_id",
      "TenantId": "tenant_id",
      "ClientId": "azure_ad_app_client_id",
      "Scopes": "Tiny.Greet",
      "CallbackPath": "/signin-oidc"
    },
    
    
    

    Now we have an Api which demanding correct access token in request header to get the correct response. Let's continue to create a new blazor web assembly project by VS template, and choose the same authentication type.

    User's image

    You will see codes below in Program.cs which using MSAL library.

    builder.Services.AddMsalAuthentication(options =>
    {
        builder.Configuration.Bind("AzureAd", options.ProviderOptions.Authentication);
    });
    

    And you also need to modify the wwwroot->appsettings.json file to finish the configuration. Just like what I said above, please using the same Azure AD application.

    "AzureAd": {
      "Authority": "https://login.microsoftonline.com/tenant_id",
      "ClientId": "azure_ad_app_client_id",
      "ValidateAuthority": true
    }
    

    We will be able to run the blazor app and sign in with Microsoft account now. The rest is to generate an access token which containing the correct scope(we exposed in Azure AD portal and set in the API project). We can refer to this document to use TokenProvider. After sign in the blazor app, using codes below could help us generate an access token.

    @inject IAccessTokenProvider TokenProvider
    
    protected override async Task OnInitializedAsync()
    {
        var result = await TokenProvider.RequestAccessToken(new AccessTokenRequestOptions
            {
                Scopes = new[] { "api://client_id_exposing_api/Tiny.Read" }
            });
        if (result.TryGetToken(out var token))
        {
            Console.WriteLine($"Access Token: {token.Value}");
            var res = token.Value;
        }
    }
    

    Finally, we can send http request in blazor frontend client app to API endpoint to get the desired response.


    If the answer is the right solution, please click "Accept Answer" and kindly upvote it. If you have extra questions about this answer, please click "Comment".

    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.

    Best regards,
    Tiny

    1 person found this answer helpful.

2 additional answers

Sort by: Most helpful
  1. Bruce (SqlWork.com) 67,251 Reputation points
    2024-09-13T15:56:53.63+00:00

    if you are using azure ad for authentication, then you want to use the MSAL library.

    https://learn.microsoft.com/en-us/entra/msal/dotnet/

    unfortunately, there is no template, you need to manually add the support. the approach will vary depending on if using server or client Blazor:

    Blazor WASM Msal:
    https://learn.microsoft.com/en-us/aspnet/core/blazor/security/webassembly/standalone-with-microsoft-entra-id?view=aspnetcore-8.0

    Blazor Server Msal example (its net 7, need to upgrade to your version):

    https://github.com/Azure-Samples/ms-identity-blazor-server/blob/main/WebApp-OIDC/MyOrg/README.md

    note: blazor server azure ad authenication is basically the same as when using razor pages or mvc:

    https://learn.microsoft.com/en-us/aspnet/core/security/authentication/azure-active-directory/?view=aspnetcore-8.0

    0 comments No comments

  2. Clemens Mattner 20 Reputation points
    2024-09-18T07:18:53.5733333+00:00

    Hi @Tiny Wang-MSFT ,

    thanks for the help. I followed your tutorial, and I'm stuck on the last step.

    I've set everything up with my backend running at https://localhost:7291 and my frontend at https://localhost:7290.

    On the frontend I'm able to log in successfully, but I don't receive any token.

    On the line Scopes = new[] { "api://client_id_exposing_api/Tiny.Read" }

    I replaced client_id_exposing_api with the client id from the app settings. (Hope that is correct)

    That is the response I'm getting:

    {

    "error": "invalid_resource",

    "error_description": "AADSTS500011: The resource principal named api://5550be71-...3df6c was not found in the tenant named 0d156cc0-...-566ae64a63ef. This can happen if the application has not been installed by the administrator of the tenant or consented to by any user in the tenant. You might have sent your authentication request to the wrong tenant. Trace ID: Correlation ID: Timestamp: ",

    "error_codes": [

    500011

    ],

    "error_uri": "https://login.microsoftonline.com/error?code=500011"

    }

    Maybe something is missing in our azure configuration?

    0 comments No comments

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.