2016-11-30 7 views
0

Я занимаюсь учебными пособиями here для создания моего приложения. Все работает хорошо на стороне аутентификации. Теперь проблема заключается в том, что я перехожу на сервер ресурсов для извлечения данных. Если я поместил [Авторизовать] по любому методу на сервере ресурсов, я получаю сообщение об ошибке «Нет» Access-Control-Allow-Origin 'заголовок присутствует на запрошенном ресурсе. Следовательно, Origin не имеет права доступа. Ответ имеет статус HTTP код 500. ". Если я удалю это все работает нормально, но я не могу получить доступ к любой претензии или роли, связанные с пользователемНет заголовка «Access-Control-Allow-Origin» присутствует в запрошенной ошибке ресурса, когда [Authorize] помещается на любой метод в контроллере

Выдержки из startup.cs кода моего AuthServer выглядит следующим образом

public class Startup 
{ 
    string PublicHostUri { get { return "https://localhost:44354"; } } 
    private readonly IHostingEnvironment _environment; 
    public Startup(IHostingEnvironment env) 
    { 
     var builder = new ConfigurationBuilder() 
      .SetBasePath(env.ContentRootPath) 
      .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true) 
      .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true); 

     if (env.IsEnvironment("Development")) 
     { 
      // This will push telemetry data through Application Insights pipeline faster, allowing you to view results immediately. 
      builder.AddApplicationInsightsSettings(developerMode: true); 
     } 
     _environment = env; 
     builder.AddEnvironmentVariables(); 
     Configuration = builder.Build(); 
    } 

    public IConfigurationRoot Configuration { get; } 


    public void ConfigureServices(IServiceCollection services) 
    { 

     var connectionString = Configuration["Data:UserAccConnection:ConnectionString"]; 
     var migrationsAssembly = typeof(Startup).GetTypeInfo().Assembly.GetName().Name; 
     var cert = new X509Certificate2(Path.Combine(_environment.ContentRootPath, "reportbook.auth.pfx"), ""); 

     var reportbookConnnectionString = Configuration["Data:ReportBookDbConnection:connectionString"]; 
     services.AddDbContext<ReportBookDbContext>(options => 
      options.UseSqlServer(reportbookConnnectionString)); 

     // Add framework services. 
     services.AddApplicationInsightsTelemetry(Configuration); 


     services.AddDbContext<UserDbContext>(options => 
      options.UseSqlServer(connectionString, b => b.MigrationsAssembly(migrationsAssembly))); 

     // Register the Identity services. 
     services.AddIdentity<ApplicationUser, UserRole>() 
      .AddEntityFrameworkStores<UserDbContext, Guid>() 
      .AddDefaultTokenProviders(); 

     services.AddCors(); 
     services.AddMvc(); 

     services.AddIdentityServer() 
      .AddDefaultEndpoints() 

      .AddOperationalStore(builder => 
      builder.UseSqlServer(connectionString, 
      options => options.MigrationsAssembly(migrationsAssembly))) 

      .AddConfigurationStore(builder => 
      builder.UseSqlServer(connectionString, 
      options => options.MigrationsAssembly(migrationsAssembly))) 

      .SetSigningCredential(cert) 
      .AddAspNetIdentity<ApplicationUser>() 
      .AddProfileService<IdentityWithAdditionalClaimsProfileService>(); 

     services.Configure<MvcOptions>(options => 
     { 
      options.Filters.Add(new RequireHttpsAttribute()); 
     }); 

     services.AddTransient<IProfileService, IdentityWithAdditionalClaimsProfileService>(); 
     services.AddTransient<IUnitOfWorkAsync, UnitOfWork>(); 
     services.AddScoped<IDataContextAsync, ReportBookDbContext>(); 



    } 

    // This method gets called by the runtime. Use this method to configure the HTTP request pipeline 
    public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) 
    { 
     loggerFactory.AddConsole(Configuration.GetSection("Logging")); 
     loggerFactory.AddDebug(); 
     if (env.IsDevelopment()) 
     { 
      app.UseDeveloperExceptionPage(); 
      app.UseDatabaseErrorPage(); 
      InitializeDbTestData(app); 
     }else 
     { 
      app.UseExceptionHandler(
      builder => 
      { 
       builder.Run(
       async context => 
       { 
        context.Response.StatusCode = (int)HttpStatusCode.InternalServerError; 
        context.Response.Headers.Add("Access-Control-Allow-Origin", "*"); 

        var error = context.Features.Get<IExceptionHandlerFeature>(); 
        if (error != null) 
        { 
         await context.Response.WriteAsync(error.Error.Message).ConfigureAwait(false); 
        } 
       }); 
      }); 
     } 

     app.UseApplicationInsightsRequestTelemetry(); 

     app.UseApplicationInsightsExceptionTelemetry(); 

     app.UseStaticFiles(); 
     app.UseCors(builder => 
      builder.AllowAnyOrigin() 
      .AllowCredentials() 
      .AllowAnyHeader() 
      .AllowAnyMethod()); 

     app.UseCsp(options => options.DefaultSources(directive => directive.Self()) 
      .ImageSources(directive => directive.Self() 
       .CustomSources("*")) 
      .ScriptSources(directive => directive.Self() 
       .UnsafeInline()) 
      .StyleSources(directive => directive.Self() 
       .UnsafeInline())); 

     app.UseXContentTypeOptions(); 
     app.UseXfo(options => options.Deny()); 
     app.UseXXssProtection(options => options.EnabledWithBlockMode()); 

     app.UseIdentity(); 
     app.UseIdentityServer(); 

     //app.UseMvc(routes => 
     //{ 
     // routes.MapRoute(
     //  name: "default", 
     //  template: "{controller=Home}/{action=Index}/{id?}"); 
     //}); 

     app.UseMvcWithDefaultRoute(); 
     app.UseMvc(); 
     //databaseInitializer.Seed(app).GetAwaiter().GetResult(); 
    } 
    private static void InitializeDbTestData(IApplicationBuilder app) 
    { 
     using (var scope = app.ApplicationServices.GetService<IServiceScopeFactory>().CreateScope()) 
     { 
      scope.ServiceProvider.GetRequiredService<PersistedGrantDbContext>().Database.Migrate(); 
      scope.ServiceProvider.GetRequiredService<ConfigurationDbContext>().Database.Migrate(); 
      scope.ServiceProvider.GetRequiredService<UserDbContext>().Database.Migrate(); 

      var context = scope.ServiceProvider.GetRequiredService<ConfigurationDbContext>(); 

      if (!context.Clients.Any()) 
      { 
       foreach (var client in Clients.Get()) 
       { 
        context.Clients.Add(client.ToEntity()); 
       } 
       context.SaveChanges(); 
      } 


      if (!context.Scopes.Any()) 
      { 
       foreach (var clientSope in Scopes.Get()) 
       { 
        context.Scopes.Add(clientSope.ToEntity()); 
       } 
       context.SaveChanges(); 
      } 
      var userManager = scope.ServiceProvider.GetRequiredService<UserManager<ApplicationUser>>(); 
      var roleManager = scope.ServiceProvider.GetRequiredService<RoleManager<UserRole>>(); 

      if (!userManager.Users.Any()) 
      { 
       foreach (var newUser in Users.Get()) 
       { 
        ApplicationUser user = new ApplicationUser(); 
        user.Id = new Guid(); 
        user.EmailConfirmed = true; 
        user.UserName = newUser.Email; 
        user.UserNo = newUser.UserNo; 
        user.FirstName = newUser.FirstName; 
        user.LastName = newUser.LastName; 
        user.Gender = newUser.Gender; 
        user.UserCategory = newUser.UserCategory; 
        user.ZoneInfo = newUser.ZoneInfo; 
        userManager.CreateAsync(user, "Password123!").Wait(); 
        userManager.AddClaimAsync(user, new Claim("UserCategory", user.UserCategory)).Wait(); 
        foreach (var role in newUser.UserRoles) 
        { 
         if (!roleManager.RoleExistsAsync(role).GetAwaiter().GetResult()) 
         { 
          UserRole userRole = new UserRole(); 
          userRole.Id = new Guid(); 
          userRole.Name = role; 
          roleManager.CreateAsync(userRole).Wait(); 
         } 
         userManager.AddToRoleAsync(user, role).Wait(); 
         userManager.AddClaimAsync(user, new Claim(JwtClaimTypes.Role, role)).Wait(); 
        } 
       } 
      } 
     } 
    } 
} 

Выдержки из startup.cs файла из ресурсов сервера заключается в следующем

public class Startup 
    { 
     private IHostingEnvironment _env { get; set; } 
     public Startup(IHostingEnvironment env) 
     { 
      _env = env; 
      var builder = new ConfigurationBuilder() 
       .SetBasePath(env.ContentRootPath) 
       .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true) 
       .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true); 

      if (env.IsEnvironment("Development")) 
      { 
       // This will push telemetry data through Application Insights pipeline faster, allowing you to view results immediately. 
       builder.AddApplicationInsightsSettings(developerMode: true); 
      } 

      builder.AddEnvironmentVariables(); 
      Configuration = builder.Build(); 
     } 

     public IConfigurationRoot Configuration { get; } 
     //private static void InitializeDbTestData(IApplicationBuilder app) 
     //{ 
     // using (var scope = app.ApplicationServices.GetService<IServiceScopeFactory>().CreateScope()) 
     // { 
     //  scope.ServiceProvider.GetRequiredService<ReportBookDbContext>().Database.Migrate(); 
     // } 
     //} 

     // This method gets called by the runtime. Use this method to add services to the container 
     public void ConfigureServices(IServiceCollection services) 
     { 
      var folderForKeyStore = Configuration["Data:keystore:KeyStoreFolderWhichIsBacked"]; 
      var cert = new X509Certificate2(Path.Combine(_env.ContentRootPath, "reportbook.auth.pfx"), ""); 

      services.AddDataProtection() 
       .SetApplicationName("ReportBook") 
       .ProtectKeysWithDpapiNG("CERTIFICATE=Hashid:" + cert.Thumbprint,flags: DpapiNGProtectionDescriptorFlags.None); 

      services.AddDbContext<ReportBookDbContext>(options => 
       options.UseSqlServer(Configuration["Data:ReportBookDbConnection:connectionString"], 
       b => b.MigrationsAssembly("ReportBook.Resource")));   

      // Add framework services. 
      services.AddCors(); 
      services.AddApplicationInsightsTelemetry(Configuration); 
      services.AddTransient<IEmailSender, AuthMessageSender>(); 
      services.AddTransient<ISmsSender, AuthMessageSender>(); 



      services.AddMvc(); 
     } 

     // This method gets called by the runtime. Use this method to configure the HTTP request pipeline 
     public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) 
     { 
      loggerFactory.AddConsole(Configuration.GetSection("Logging")); 
      loggerFactory.AddDebug(); 

      app.UseDeveloperExceptionPage(); 

      app.UseStatusCodePagesWithReExecute("/error"); 

      if (env.IsDevelopment()) 
      { 
       //InitializeDbTestData(app); 
      } 

      JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear(); 

      IdentityServerAuthenticationOptions identityServerValidationOptions = new IdentityServerAuthenticationOptions 
      { 
       Authority = "https://localhost:44354/", 
       ScopeName = "resource_server", 
       ScopeSecret = new IdentityServer4.Models.Secret("scopeSecret".Sha256()).ToString(), 
       AutomaticAuthenticate = true, 
       SupportedTokens = SupportedTokens.Both, 
       AutomaticChallenge = true 
      }; 
      app.UseIdentityServerAuthentication(identityServerValidationOptions); 

      app.UseApplicationInsightsRequestTelemetry(); 

      app.UseApplicationInsightsExceptionTelemetry(); 

      app.UseExceptionHandler(
       builder => 
       { 
        builder.Run(
        async context => 
        { 
         context.Response.StatusCode = (int)HttpStatusCode.InternalServerError; 
         context.Response.Headers.Add("Access-Control-Allow-Origin", "*"); 

         var error = context.Features.Get<IExceptionHandlerFeature>(); 
         if (error != null) 
         { 
          await context.Response.WriteAsync(error.Error.Message).ConfigureAwait(false); 
         } 
        }); 
       }); 
      app.UseCors(builder => 
       builder.AllowAnyOrigin() 
       .AllowAnyHeader() 
       .AllowAnyMethod() 
       .AllowCredentials()); 
      app.UseMvc(); 
     } 
    } 

Ниже приводится выдержка из контроллера, метод которого я пытаюсь достичь

[HttpGet("GetInstitutions")] 
     //[Authorize] 
     public IActionResult GetInstitutions([FromQuery]InstitutionSearchQry model) 
     { 
      var authorisation = Request.Headers["Authorization"]; 
      bool auth = User.Identity.IsAuthenticated; 
      IEnumerable<Institution> _institutions = null; 
      string userCategory = User.Claims.Where(a => a.Type == "UserCategory").Select(a => a.Value).FirstOrDefault().ToString(); 
      string zoneInfo = User.Claims.Where(a => a.Type == "ZoneInfo").Select(a => a.Value).FirstOrDefault().ToString(); 
      string userNo = User.Claims.Where(a => a.Type == "UserNo").Select(a => a.Value).FirstOrDefault().ToString(); 
      bool admin = User.IsInRole("Admin"); 

      List<Student> students = new List<Student>(); 

      //Institution institution = _institutionService.Find(a => a.InstitutionID == zoneInfo); 
      var pagination = Request.Headers["Pagination"]; 

      if (!string.IsNullOrEmpty(pagination)) 
      { 
       string[] vals = pagination.ToString().Split(','); 
       int.TryParse(vals[0], out page); 
       int.TryParse(vals[1], out pageSize); 
      } 

      switch (userCategory) 
      { 
       case "Guardian": 
        { 

         students = _guardianService.GetStudents(userNo).ToList(); 
         _institutions = _admissionService.GetInstitutions(students.Select(a => a.StudentID).ToList(),model.StartYear,model.EndYear, s => s.Term.AcademicYear.Institution.UniversityInstitutes.Select(a => a.University)); 
        } 
        break; 
       case "Student": 
        { 
         _institutions = _admissionService.GetInstitution(userNo,s=>s.Term.AcademicYear.Institution.UniversityInstitutes.Select(a=>a.University)); 
        } 
        break; 
       default: 
        { 
         _institutions = _institutionService.GetInstitutions(a => a.AdministrativeStructure.ZoneInfo == zoneInfo && a.Level.LevelName==model.Level, page, pageSize, out totalCount, s => s.AdministrativeStructure, s => s.Level,s=>s.UniversityInstitutes.Select(a=>a.University)); 
        } 
        break; 
      } 
      if (!String.IsNullOrEmpty(model.Level) && model.Level != "myschool") 
      { 
       _institutions = _institutions.Where(a => a.Level.LevelName == model.Level); 
      } 

      var totalPages = (int)Math.Ceiling((double)totalCount/pageSize); 


      Response.AddPagination(page, pageSize, totalCount,totalPages); 
      Response.AddIdentityInfo(userCategory, admin, userNo, zoneInfo); 
      IEnumerable<InstitutionDataViewModel> _instDataModel = Mapper.Map<IEnumerable<Institution>, IEnumerable<InstitutionDataViewModel>>(_institutions); 
      return new OkObjectResult(_instDataModel); 
     } 

Следующая угловая 2-код, откуда вызов на сервере ресурсов

@Injectable() 
export class InstitutionService { 
    private resourceApiUrl: string; 
    private headers: Headers; 
    private storage: any; 
    private actionUrl: string; 
    public totalItems: number; 


    constructor(private _http: Http, 
     private itemsService: ItemsService, 
     private _configuration: Configuration, 
     private _router: Router, 
     private _authService: AuthService) { 
     this.resourceApiUrl = `${_configuration.resourceServer}api/Institution/`; 
    } 
    private SetHeaders(page?: number, itemsPerPage?: number) { 
     this.headers = new Headers(); 
     this.headers.append('Content-Type', 'application/json'); 
     this.headers.append('Accept', 'application/json'); 
     if (page != null && itemsPerPage != null) { 
      this.headers.append('Pagination', page + ',' + itemsPerPage); 
     } 

     var token = this._authService.GetToken(); 
     if (token !== "") { 
      let tokenValue = 'Bearer ' + token; 
      console.log("tokenValue:" + tokenValue); 
      this.headers.append('Authorization', tokenValue); 
     } 
    } 
    public GetInstitutions = (InstitutionSearchQry?: any, page?: number, itemsPerPage?: number): Observable<PaginatedResult<IInstitution[]>> => { 
     this.SetHeaders(page, itemsPerPage); 
     var paginatedResult: PaginatedResult<IInstitution[]> = new PaginatedResult<IInstitution[]>(); 
     let options = new RequestOptions({ headers: this.headers, body: '' }); 
     if (!InstitutionSearchQry.level) { 
      this.actionUrl = "GetInstitutions"; 
     } else { 
      this.actionUrl = "GetInstitutions/", InstitutionSearchQry; 

     } 

     return this._http.get(this.resourceApiUrl + this.actionUrl, options) 
      .map((res: Response) => { 
       //console.log(res.headers.keys()); 
       paginatedResult.result = res.json(); 
       if (res.headers.get("Pagination") != null) { 
        //var pagination = JSON.parse(res.headers.get("Pagination")); 
        var paginationHeader: Pagination = this.itemsService.getSerialized<Pagination>(JSON.parse(res.headers.get("Pagination"))); 
        paginatedResult.pagination = paginationHeader; 
       } 
       if (res.headers.get("IdentityInfo") != null) { 
        var identityInfo: IdentityInfo = this.itemsService.getSerialized<IdentityInfo>(JSON.parse(res.headers.get("IdentityInfo"))); 
        paginatedResult.identityInfo = identityInfo; 
       } 
       this.totalItems = paginatedResult.pagination.TotalItems; 
       return paginatedResult; 
      }).catch(this.handleError); 
    }; 


} 

Так в основном информация авторизации предоставляется на стороне AuthServer не достигает сервера ресурсов. Как видно, я добавил службу CORS в оба файла.

ответ

0

Используйте этот плагин для браузера Chrome. get from here

+0

Извините, для меня это не сработало. Я действительно застрял здесь прямо сейчас –