Oauth 2.0 Net内核、JWT和OpenIdConnectServer

Oauth 2.0 Net内核、JWT和OpenIdConnectServer,oauth-2.0,asp.net-identity,asp.net-core,jwt,aspnet-contrib,Oauth 2.0,Asp.net Identity,Asp.net Core,Jwt,Aspnet Contrib,我试图理解Asp.NETCore中关于JWT令牌的所有内容。在经历了大量的误会之后,我陷入了困境。我的任务是使WebApi服务器具有两个控制器(受保护和不受保护)。我应该从服务器授予令牌,并能够获得受保护的资源。当我运行服务器并尝试从postman获取受保护的资源时,一切似乎都很好。但当我在自己身上做同样的事情时,从另一个领域我有了奇怪的事情。我可以获取未受保护的资源,但如果出现以下错误,我无法获取受保护的资源: XMLHttpRequest无法加载http://localhost:10450/

我试图理解Asp.NETCore中关于JWT令牌的所有内容。在经历了大量的误会之后,我陷入了困境。我的任务是使WebApi服务器具有两个控制器(受保护和不受保护)。我应该从服务器授予令牌,并能够获得受保护的资源。当我运行服务器并尝试从postman获取受保护的资源时,一切似乎都很好。但当我在自己身上做同样的事情时,从另一个领域我有了奇怪的事情。我可以获取未受保护的资源,但如果出现以下错误,我无法获取受保护的资源:

XMLHttpRequest无法加载http://localhost:10450/api/prvalues. 对飞行前请求的响应未通过访问控制检查:请求的资源上不存在“访问控制允许来源”标头。起源'http://localhost:10377因此,不允许访问。

为了清楚起见,我展示了我所有的努力。我的project.json看起来像

  "dependencies": {
     "AspNet.Security.OpenIdConnect.Server": "1.0.0-beta4",
     "EntityFramework.Core": "7.0.0-rc1-final",
     "EntityFramework.InMemory": "7.0.0-rc1-final",
     "Microsoft.AspNet.Authentication.JwtBearer": "1.0.0-rc1-final",
     "Microsoft.AspNet.Diagnostics": "1.0.0-rc1-final",
     "Microsoft.AspNet.Identity.EntityFramework": "3.0.0-rc1-final",
     "Microsoft.AspNet.IISPlatformHandler": "1.0.0-rc1-final",
     "Microsoft.AspNet.Mvc": "6.0.0-rc1-final",
     "Microsoft.AspNet.Server.Kestrel": "1.0.0-rc1-final",
     "Microsoft.AspNet.StaticFiles": "1.0.0-rc1-final",
     "Microsoft.Extensions.Configuration.FileProviderExtensions": "1.0.0-rc1-final",
     "Microsoft.Extensions.Logging": "1.0.0-rc1-final",
     "Microsoft.Extensions.Logging.Console": "1.0.0-rc1-final",
     "Microsoft.Extensions.Logging.Debug": "1.0.0-rc1-final",
     "NWebsec.Middleware": "1.0.0-gamma-39",
     "Microsoft.AspNet.Mvc.Cors": "6.0.0-rc1-final",
     "Microsoft.AspNet.Cors": "6.0.0-rc1-final"
},
我的
Startup.ConfigureServices()
看起来像

  "dependencies": {
     "AspNet.Security.OpenIdConnect.Server": "1.0.0-beta4",
     "EntityFramework.Core": "7.0.0-rc1-final",
     "EntityFramework.InMemory": "7.0.0-rc1-final",
     "Microsoft.AspNet.Authentication.JwtBearer": "1.0.0-rc1-final",
     "Microsoft.AspNet.Diagnostics": "1.0.0-rc1-final",
     "Microsoft.AspNet.Identity.EntityFramework": "3.0.0-rc1-final",
     "Microsoft.AspNet.IISPlatformHandler": "1.0.0-rc1-final",
     "Microsoft.AspNet.Mvc": "6.0.0-rc1-final",
     "Microsoft.AspNet.Server.Kestrel": "1.0.0-rc1-final",
     "Microsoft.AspNet.StaticFiles": "1.0.0-rc1-final",
     "Microsoft.Extensions.Configuration.FileProviderExtensions": "1.0.0-rc1-final",
     "Microsoft.Extensions.Logging": "1.0.0-rc1-final",
     "Microsoft.Extensions.Logging.Console": "1.0.0-rc1-final",
     "Microsoft.Extensions.Logging.Debug": "1.0.0-rc1-final",
     "NWebsec.Middleware": "1.0.0-gamma-39",
     "Microsoft.AspNet.Mvc.Cors": "6.0.0-rc1-final",
     "Microsoft.AspNet.Cors": "6.0.0-rc1-final"
},
public void配置服务(IServiceCollection服务) {

        services.AddCors(options =>
        {
            options.AddPolicy("AllowAllOrigins",
                    builder =>
                    {
                        builder.AllowAnyOrigin();
                        builder.AllowAnyHeader();
                    });
        });

        services.AddEntityFramework()
           .AddInMemoryDatabase()
           .AddDbContext<ApplicationDbContext<ApplicationUser, Application, IdentityRole, string>>(options => {
               options.UseInMemoryDatabase();
           });
        services.AddScoped<IAuthStore<ApplicationUser,Application>, AuthStore<ApplicationUser, Application, IdentityRole, 
            ApplicationDbContext<ApplicationUser, Application, IdentityRole, string>, string>>();
        services.AddScoped<AuthManager<ApplicationUser, Application>>();
        services.AddIdentity<ApplicationUser, IdentityRole>(options =>
        {
            options.Password = new PasswordOptions()
            {
                RequiredLength = 1,
                RequireDigit = false,
                RequireLowercase = false,
                RequireUppercase = false,
                RequireNonLetterOrDigit = false

            };
        }).AddEntityFrameworkStores<ApplicationDbContext<ApplicationUser, Application, IdentityRole, string>>().AddDefaultTokenProviders();
        services.AddAuthentication();

        // Add framework services.

        services.AddCaching();
        services.AddMvc();
    }
最后,我的
AthorizationProvider.GrantResourceOwnerCredentials()
(我使用AspNet.Security.OpenIdConnect.Server)是:


正如我所说,我有这样的请求的cors错误。但是如果我尝试获取不受保护的资源(从控制器中删除
[Authorize]
属性),一切正常。

我找到了解决方案。当我在
AthorizationProvider.GrantResourceOwnerCredentials()中设置资源时,我设置了“”,但在
usejwtbeareraauthentication
中间件中,我在authority选项中设置了“”(末尾包含斜杠)。这是一个非常愚蠢的错误。

您是否尝试过在github上的Cors示例中使用
allowRedentials()
AllowAnyMethod()
一起使用
    public override async Task GrantResourceOwnerCredentials(GrantResourceOwnerCredentialsContext context)
    {

        #region UserChecking
        var manager = context.HttpContext.RequestServices.GetRequiredService<AuthManager<ApplicationUser, Application>>();

        var user = await manager.FindByNameAsync(context.UserName);
        if (user == null)
        {
            context.Rejected(
                error: OpenIdConnectConstants.Errors.InvalidGrant,
                description: "Invalid credentials.");

            return;
        }

        // Ensure the user is not already locked out.
        if (manager.SupportsUserLockout && await manager.IsLockedOutAsync(user))
        {
            context.Rejected(
                error: OpenIdConnectConstants.Errors.InvalidGrant,
                description: "Account locked out.");

            return;
        }

        // Ensure the password is valid.
        if (!await manager.CheckPasswordAsync(user, context.Password))
        {
            context.Rejected(
                error: OpenIdConnectConstants.Errors.InvalidGrant,
                description: "Invalid credentials.");

            if (manager.SupportsUserLockout)
            {
                await manager.AccessFailedAsync(user);

                // Ensure the user is not locked out.
                if (await manager.IsLockedOutAsync(user))
                {
                    context.Rejected(
                        error: OpenIdConnectConstants.Errors.InvalidGrant,
                        description: "Account locked out.");
                }
            }

            return;
        }

        if (manager.SupportsUserLockout)
        {
            await manager.ResetAccessFailedCountAsync(user);
        }


        if (context.Request.ContainsScope(OpenIdConnectConstants.Scopes.Profile) &&
           !context.Request.ContainsScope(OpenIdConnectConstants.Scopes.Email) &&
            string.Equals(await manager.GetUserNameAsync(user),
                          await manager.GetEmailAsync(user),
                          StringComparison.OrdinalIgnoreCase))
        {
            context.Rejected(
                error: OpenIdConnectConstants.Errors.InvalidRequest,
                description: "The 'email' scope is required.");

            return;
        }

        #endregion

        var identity = await manager.CreateIdentityAsync(user, context.Request.GetScopes());

        var ticket = new AuthenticationTicket(
           new ClaimsPrincipal(identity),
           new AuthenticationProperties(),
           context.Options.AuthenticationScheme);

        //ticket.SetResources(context.Request.GetResources());
        // When I tested with postman
        //ticket.SetResources(new[] { "http://localhost:10450/" });
        ticket.SetResources(new[] { "http://localhost:10377" });
        ticket.SetScopes(context.Request.GetScopes());

        context.Validated(ticket);


    }
$http.defaults.headers.common['Authorization'] = 'Bearer ' + 'token here';
return $http.get('http://localhost:10450/' + 'api/prvalues');