MSAL.Net No account or login hint was passed to the AcquireTokenSilent call

不羁的心 提交于 2020-05-17 07:05:19

问题


I have seen many same or similar questions, and tried all their answers if there was one, but none of those works for me.

I'm using this example from Microsoft's Github account as my project base.

It works well for just signing in users.

The project has 1 WebApi, 1 Angular App.

Then I followed this Microsoft example to add code to call Graph API. Here is the controller code:

[Authorize]
[Route("api/[controller]")]
[ApiController]
public class BillsController : ControllerBase
{
    static readonly string[] scopeRequiredByApi = new string[] { "access_as_user" };
    readonly ITokenAcquisition tokenAcquisition;
    readonly WebOptions webOptions;

    public BillsController(ITokenAcquisition tokenAcquisition,
                          IOptions<WebOptions> webOptionValue)
    {
        this.tokenAcquisition = tokenAcquisition;
        this.webOptions = webOptionValue.Value;
    }

    [HttpGet]
    [AuthorizeForScopes(Scopes = new[] { Constants.ScopeUserRead, Constants.ScopeMailRead })]
    public async Task<IActionResult> Profile()
    {
        HttpContext.VerifyUserHasAnyAcceptedScope(scopeRequiredByApi);

        var subject = string.Empty;
        try
        {
            // Initialize the GraphServiceClient. 
            Graph::GraphServiceClient graphClient = GetGraphServiceClient(new[] { Constants.ScopeUserRead, Constants.ScopeMailRead });

            var me = await graphClient.Me.Request().GetAsync();
            // Get user photo
            var messages = await graphClient.Me.MailFolders.Inbox.Messages.Request().GetAsync();
            subject = messages.First().Subject;
            return Ok(subject);
        }
        catch (System.Exception ex)
        {
            throw ex;
        }
    }

    private Graph::GraphServiceClient GetGraphServiceClient(string[] scopes)
    {
        return GraphServiceClientFactory.GetAuthenticatedGraphClient(async () =>
        {
            string result = await tokenAcquisition.GetAccessTokenForUserAsync(scopes);
            return result;
        }, webOptions.GraphApiUrl);
    }
}

For Startup.cs

    public void ConfigureServices(IServiceCollection services)
    {
        // Setting configuration for protected web api
        services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
            .AddProtectedWebApi(Configuration);

        services.AddWebAppCallsProtectedWebApi(Configuration, new string[] { Constants.ScopeUserRead, Constants.ScopeMailRead })
            .AddInMemoryTokenCaches();

        services.AddOptions();
        services.AddGraphService(Configuration);

        // Creating policies that wraps the authorization requirements
        services.AddAuthorization();

        services.AddDbContext<TodoContext>(opt => opt.UseInMemoryDatabase("TodoList"));

        services.AddControllers();

        // Allowing CORS for all domains and methods for the purpose of sample
        services.AddCors(o => o.AddPolicy("default", builder =>
        {
            builder.AllowAnyOrigin()
                   .AllowAnyMethod()
                   .AllowAnyHeader();
        }));
    }

    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        if (env.IsDevelopment())
        {
            // Since IdentityModel version 5.2.1 (or since Microsoft.AspNetCore.Authentication.JwtBearer version 2.2.0),
            // Personal Identifiable Information is not written to the logs by default, to be compliant with GDPR.
            // For debugging/development purposes, one can enable additional detail in exceptions by setting IdentityModelEventSource.ShowPII to true.
            // Microsoft.IdentityModel.Logging.IdentityModelEventSource.ShowPII = true;
            app.UseDeveloperExceptionPage();
        }
        else
        {
            // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
            app.UseHsts();
        }

        app.UseExceptionHandler("/error");

        app.UseCors("default");
        app.UseHttpsRedirection();
        app.UseCookiePolicy();
        app.UseRouting();
        app.UseAuthentication();
        app.UseAuthorization();
        app.UseEndpoints(endpoints =>
        {
            endpoints.MapControllers();
        });
    }

On the Angular App, I added one button to call this Profile() controller action.

todo-view.component.ts

  getEmails(): void {
    this.service.getEmails().subscribe({
      next: (emails: any) => {
        alert(emails);
      },
      error: (err: any) => {
        console.log("error happened~!");
        console.log(err);
      }
    });
  }

todo-view.component.html

<button (click)="getEmails();">Get Emails</button>


I added the below code into my Startup.cs and removed the AddWebAppCallsProtectedWebApi. services.AddProtectedWebApiCallsProtectedWebApi(Configuration).AddInMemoryTokenCaches();

Now it throws me a different error message:

来源:https://stackoverflow.com/questions/61524182/msal-net-no-account-or-login-hint-was-passed-to-the-acquiretokensilent-call

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!