1

I have an ASP.NET Core 6 Web API and a single page quasar (Vue.js) app.

I followed the msal-browser documentation to set up Azure AD App registration for both apps and was able to get the msal-browser demo app (an Angular SPA) and API authenticating.

Utilising the same Azure AD app registration I have been trying to sub in my own API and Vue js app.

I can login and get a token with my Vue js app. The token contains my AzAD details

I can access AllowAnonymous routes on my API from my Vue js App but I get a 401 UnAuthorized response when I try and use the AD token on my API.

A couple of things I suspect I might not be doing correctly

  1. Not requesting with the scope properly
  2. Not sending the request to the api properly
  3. Not loading the config in the api properly

Edit

It looks like the problem is that I am not sending the request to the api properly.

I pointed the msal-browser demo Angular app at my api and it was able to retrieve the TodoList from the endpoint I replicated. Whereas my Vue app could only fetch the data when the endpoint had no [Authorize] attribute.

I have tried Swagger, Postman and my Vue.js app with the token copied from the Angular app and with the token acquired by my Vue app and get a 401 Authorization response with all. I have verified the tokens on jwt.ms.

The msal-browser doco for using the token only says to include the header Authorization: Bearer <token>.

I can't really see whats going on in the Angular client to prepare the request, but the Angular SPA demo app has access to more info, such as the app's Az clientId, authority: https://login.microsoftonline.com/(tenantId), redirectURi and scopes.

Any help in getting one of Swagger, Postman or My Vue app to use the Azure AD token against the api would be appreciated.

End Edit

Here is some of my code

msal-browser prop up

const msalConfig = {
    auth: {
        clientId: '<< removed >>',
        authority: "https://login.microsoftonline.com/<< removed >>",
        scopes: ['api://<< removed >>/access_as_user'],
        redirectUri: "http://localhost:4200",
    },
    cache: {
        cacheLocation: "sessionStorage", 
        storeAuthStateInCookie: false, 
    }
};

const msalInstance = new msal.PublicClientApplication(msalConfig);

const loginRequest = {
    // scopes: ["openid", "profile", "User.Read"]
    scopes: ["openid", "profile", "User.Read", 'api://<< removed >>/access_as_user']
};

function SignIn() {
    msalInstance.loginPopup(loginRequest)
        .then(loginResponse => {
        state.signedIn = true;
        state.signedInAs = loginResponse.account.name;
        state.idToken = loginResponse.idToken;
        state.accessToken = loginResponse.accessToken;

        console.log(loginResponse);
        }).catch(error => {
        console.log(error);
        });
}

Where I call the Api

async function FnTest(e) {
    const config = {
        headers: {
            Authorization: 'Bearer << removed >>'
        }
    }
    try {
        // axios
        const result = await api.get('/ToDos', config);
        console.log(result)
    } catch(ex) {
        console.log(ex)
    }
}

Program.cs from my Web API:

// not sure whether I am loading IConfiguration properly here
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
    .AddMicrosoftIdentityWebApi(builder.Configuration);

builder.Services.AddAuthorization();

var app = builder.Build();
...

Web API's appsettings.json:

"AzureAd": {
    "Instance": "https://login.microsoftonline.com/",
    "Domain": "<<removed>>.onmicrosoft.com",
    "TenantId": "<<removed>>",
    "ClientId": "<<removed>>"
}

Any help would be greatly appreciated. I have been at this for some time now.

Also worth noting I guess that I have had auth working on this Web API when I create my own token. I have also tried the AzAd token in the API's swagger page and get the same result

Thed
  • 125
  • 2
  • 10
  • 1
    I faced a similar structure before and you may see my [this answer](https://stackoverflow.com/a/68799358/15581227). And you can access the AllowAnonymous api means your client can successfully contact with the server. And as you've generated access token with msal.js so I think that part also worked well. So I'm afraid that really something wrong with the configuration, you may refer to [this document](https://learn.microsoft.com/en-us/azure/active-directory/develop/scenario-protected-web-api-app-configuration#starting-from-an-existing-aspnet-core-31-application) – Tiny Wang Dec 10 '21 at 07:35
  • 1
    And I also find that the document recommend to use `services.AddMicrosoftIdentityWebApiAuthentication(Configuration);` to enable Azure ad authentication – Tiny Wang Dec 10 '21 at 07:37
  • 1
    You may also decode the access token and check if it has correct scopes which will be [validated in your api](https://learn.microsoft.com/en-us/azure/active-directory/develop/scenario-protected-web-api-verification-scope-app-roles?tabs=aspnetcore). – Tiny Wang Dec 10 '21 at 07:40
  • Thanks for your helpful comments @TinyWang. It looks like the problem is with the Vue app sending the request. I pointed the Angular demo app at my api and could access secured endpoints (I edited the question to include this) – Thed Dec 11 '21 at 21:51
  • sorry I really don't know vue and I failed to write a sample. You may refer to [this sample](https://github.com/Azure-Samples/ms-identity-javascript-v2/tree/master/app) to convert to vue code. And this document.https://vuejscode.com/package?name=msal – Tiny Wang Dec 13 '21 at 07:05

0 Answers0