HttpContext.User имеет значение null, когда я вызываю защищенный веб-интерфейс Api ASP - NET Core (AzureAD) из интерфейса Angular 9. - PullRequest
0 голосов
/ 17 апреля 2020

У меня проблема с HttpContext.User в моем приложении BackEnd (веб-интерфейс Asp - Net -Core 3.1), когда защищенный веб-интерфейс вызывается из приложения angular, значение HttpContext.User равно NULL , В моем angular приложении я могу аутентифицироваться с Azure AD, поэтому, когда я делаю http-запрос, я помещаю его в заголовок: «Bearer + access_token», как требуется, чтобы вызвать мой защищенный веб-интерфейс API, вызывающий Microsoft graph Api. Если я запускаю только приложение Backend и использую Chrome, у меня нет проблем, потому что значение HttpContext.User не равно NULL, и я могу вызвать Microsoft Graph Api. Я использую библиотеку MSAL (в обоих приложениях) для входа в Azure AD, компонент-перехватчик в angular для заполнения заголовка.

это Startup.cs:

public class Startup
{
    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public IConfiguration Configuration { get; }

    // This method gets called by the runtime. Use this method to add services to the container.
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddCors(options =>
        {
            options.AddPolicy("CorsPolicy", builder => builder.WithOrigins("http://localhost:4200")
          .AllowAnyMethod()
          .AllowAnyHeader()
          .AllowCredentials());
        });
        services.AddAuthentication(AzureADDefaults.BearerAuthenticationScheme)
            .AddAzureADBearer(options => Configuration.Bind("AzureAd", options));
        services.AddMicrosoftIdentityPlatformAuthentication(Configuration)
       .AddMsal(Configuration, new string[] { Constants.Constants.ScopeUserRead     })
       .AddInMemoryTokenCaches();
        services.AddGraphService(Configuration);
        services.AddControllers();

    }

    // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseCors("CorsPolicy");
        app.UseDeveloperExceptionPage();
    }

    app.UseHttpsRedirection();

    app.UseRouting();


    app.UseAuthentication();
    app.UseAuthorization();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapControllers();
    });
}

}

это HomeController.cs, который я вызываю в angular:

 //[Authorize]
    [Route("[controller]")]
    [ApiController]
    //[EnableCors("CorsPolicy")]
    public class HomeController : ControllerBase
    {
        readonly ITokenAcquisition tokenAcquisition;
        readonly WebOptions webOptions;
        //private readonly ILogger<HomeController> _logger;

        public HomeController(ITokenAcquisition tokenAcquisition,
                              IOptions<WebOptions> webOptionValue)
        {
            this.tokenAcquisition = tokenAcquisition;
            this.webOptions = webOptionValue.Value;
            //this._logger = logger;
            //ILogger<HomeController> logger
        }


        [HttpGet]
        [AuthorizeForScopes(Scopes = new[] { Constants.Constants.ScopeUserRead})]
        public async Task<IActionResult> Profile()
        {
            var x = HttpContext.User;
            var y = User.Identity;
            var z = User.FindFirstValue(ClaimTypes.NameIdentifier);

            // Initialize the GraphServiceClient. 
            GraphServiceClient graphClient = GetGraphServiceClient(new[] { Constants.Constants.ScopeUserRead });

            var me = await graphClient.Me.Request().GetAsync();

            return Ok("ciao");

        }

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

это custom.interceptor.ts:

    const accessTokenRequest = {
    scopes: ["user.read"]
}

@Injectable()

export class CustomInterceptor extends MsalInterceptor {

    constructor(private msalService: MsalService, private broadcast: BroadcastService) {
        super(msalService, broadcast);
    }

    public intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
        return from(this.msalService.acquireTokenSilent(accessTokenRequest).then(token => {
            const JWT = `Bearer ${token.accessToken}`;
            return req.clone({
                setHeaders: {
                    Authorization: JWT,
                },
            });
        })).pipe(mergeMap(r => next.handle(r)));
    }

}

Это приложение .component.ts:

export class AppComponent implements OnInit {
  title = 'MSAL Angular - Sample App';
  isIframe = false;
  loggedIn = false;
  // private authService: AuthService;
  private router: Router;

  constructor(private broadcastService: BroadcastService, private authService: MsalService, private httpClient: HttpClient, private injector: Injector) { }

  ngOnInit() {
    this.isIframe = window !== window.parent && !window.opener;

    this.checkAccount();

    this.broadcastService.subscribe('msal:loginSuccess', () => {
      this.checkAccount();
    });

    this.authService.handleRedirectCallback((authError, response) => {
      if (authError) {
        console.error('Redirect Error: ', authError.errorMessage);
        return;
      }

      console.log('Redirect Success: ', response.accessToken);
    });

    this.authService.setLogger(new Logger((logLevel, message, piiEnabled) => {
      console.log('MSAL Logging: ', message);
    }, {
      correlationId: CryptoUtils.createNewGuid(),
      piiLoggingEnabled: false
    }));
  }

  checkAccount() {
    this.loggedIn = !!this.authService.getAccount();
  }

  login() {
    const isIE = window.navigator.userAgent.indexOf('MSIE ') > -1 || window.navigator.userAgent.indexOf('Trident/') > -1;

    if (isIE) {
      this.authService.loginRedirect();
    } else {
      this.authService.loginPopup();
    }
  }

  logout() {
    this.authService.logout();
  }

  callApi() {
    this.httpClient.get("http://localhost:64449/home").toPromise().then((x) =>
    console.log(x)
  );
  }
}

Может ли кто-нибудь мне помочь?

Большое спасибо

...