Angular 4 Http Request Giving error unsupport Grant Type, using web API Owin Jwt 令牌

Angular 4 Http Request Giving error unsupport Grant Type, using web API Owin Jwt token

我正在尝试 post 请求获取 Auth 令牌,但 angular 4 一直给我错误,因为

Bad Request 400, Unsupported_Grant_Type

以下是我的代码:

let option: RequestOptions = new RequestOptions();
    option.headers = new Headers();
    option.headers.append("Content-Type", "application/x-www-form-urlencoded");
    //option.headers.append('access-control-allow-origin','*');

    option.body = JSON.parse(JSON.stringify({ username: username, password: password, grant_type: 'password' }));
    option.method = RequestMethod.Post;
   return  this.http.request("http://localhost:4200/oauth/token", option).map((response: Response) => {
        // login successful if there's a jwt token in the response
        let user = response.json();
        if (user && user.token) {
            // store user details and jwt token in local storage to keep user logged in between page refreshes
            localStorage.setItem('currentUser', JSON.stringify(user));
        } 
    });

并使用 Post 请求这是代码:

 let option: RequestOptions = new RequestOptions();
    option.headers = new Headers();
    option.headers.append("Content-Type", "application/x-www-form-urlencoded");
    option.method = RequestMethod.Post;
   return this.http.post('/oauth/token', JSON.stringify({ username: username, password: password, grant_type: "password" }), option)
        .map((response: Response) => {
            // login successful if there's a jwt token in the response
            let user = response.json();
            if (user && user.token) {
                // store user details and jwt token in local storage to keep user logged in between page refreshes
                localStorage.setItem('currentUser', JSON.stringify(user));
            }
        });

但在 Post man 工具中它工作正常:

这是来自 Chrome

的网络详细信息
 POST /oauth/token HTTP/1.1
Host: localhost:4200
Connection: keep-alive
Content-Length: 65
Accept: application/json, text/plain, */*
Origin: http://localhost:4200
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.113 Safari/537.36
Content-Type: application/x-www-form-urlencoded
Referer: http://localhost:4200/login?returnUrl=%2Fhome
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.8

表单数据:

{"username":"shan","password":"ShanAli!","grant_type":"password"}

我的WEB APP在4200端口

以下是 C# 的详细信息:

public void Configuration(IAppBuilder app)
    {
        app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);
        ConfigureOAuthTokenGeneration(app);
        ConfigureOAuthTokenConsumption(app);

        // ASPNETCORE_ENVIRONMENT should be set to 'Development'
        if (env != null && env.IsDevelopment())
        {
            app.UseErrorPage(ErrorPageOptions.ShowAll);
        }

        var config = new HttpConfiguration();
        ConfigureWebApi(config);
        // Swagger
        SwaggerConfig.Register(config);
        // Register routes
        WebApiConfig.Register(config);

        var builder = new ContainerBuilder();

        builder.RegisterApiControllers(Assembly.GetExecutingAssembly());

        // Run other optional steps, like registering filters,
        // per-controller-type services, etc., then set the dependency resolver
        // to be Autofac.
        var erpAssembly = Assembly.Load(ConfigurationManager.AppSettings["ErpAdapter"]);

        builder.RegisterAssemblyModules(erpAssembly);
        builder.RegisterType<ErpAdapterFactory>().As<IErpAdapterFactory>().InstancePerRequest();

        var container = builder.Build();
        var diResolver = new AutofacWebApiDependencyResolver(container);
        config.DependencyResolver = diResolver;

        // OWIN WEB API SETUP:

        // Register the Autofac middleware FIRST, then the Autofac Web API middleware,
        // and finally the standard Web API middleware.
        app.UseAutofacMiddleware(container);
        app.UseAutofacWebApi(config);

        app.UseWebApi(config);


    }
    private void ConfigureOAuthTokenGeneration(IAppBuilder app)
    {
        // Configure the db context and user manager to use a single instance per request
        app.CreatePerOwinContext(ApplicationDbContext.Create);
        app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);

        OAuthAuthorizationServerOptions OAuthServerOptions = new OAuthAuthorizationServerOptions()
        {
            //For Dev enviroment only (on production should be AllowInsecureHttp = false)
            AllowInsecureHttp = true,
            TokenEndpointPath = new PathString("/oauth/token"),
            AccessTokenExpireTimeSpan = TimeSpan.FromDays(1),
            Provider = new CustomOAuthProvider(),
            AccessTokenFormat = new CustomJwtFormat("http://localhost:40909")
        };

        // OAuth 2.0 Bearer Access Token Generation
        app.UseOAuthAuthorizationServer(OAuthServerOptions);
    }

    private void ConfigureOAuthTokenConsumption(IAppBuilder app)
    {

        var issuer = "http://localhost:40909";
        string audienceId = ConfigurationManager.AppSettings["as:AudienceId"];
        byte[] audienceSecret = TextEncodings.Base64Url.Decode(ConfigurationManager.AppSettings["as:AudienceSecret"]);

        // Api controllers with an [Authorize] attribute will be validated with JWT
        app.UseJwtBearerAuthentication(
            new JwtBearerAuthenticationOptions
            {
                AuthenticationMode = AuthenticationMode.Active,
                AllowedAudiences = new[] { audienceId },
                IssuerSecurityTokenProviders = new IIssuerSecurityTokenProvider[]
                {
                    new SymmetricKeyIssuerSecurityTokenProvider(issuer, audienceSecret)
                }
            });
    }

    private void ConfigureWebApi(HttpConfiguration config)
    {
       // config.MapHttpAttributeRoutes();

        var jsonFormatter = config.Formatters.OfType<JsonMediaTypeFormatter>().First();
        jsonFormatter.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
    }

您提供的代码不完整。

在您的 JavaScript 代码中,我没有看到您在哪里设置基本授权 header。

在您的后端代码中,您有代码讨论 AudienceID 和 Secret,但随后您在请求的 body 中传递了用户名和密码。

同样在您的后端代码中,我没有看到您查看请求并实际检查正确的 AudienceID 和 Secret 已传递的部分。

CustomOAuthProvider 类中有什么?

几年前,我写了一篇关于这个主题的详细文章,它带您完成使用 Owin 和 JWT 实现一个完全工作的 OAuth2 系统所需的所有步骤。请仔细阅读,如果您还有其他问题,请告诉我:https://eidand.com/2015/03/28/authorization-system-with-owin-web-api-json-web-tokens/

它应该可以回答您的所有问题,只要您在 JavaScript 中正确构建请求,一切都会正常。

我的额外说明,要非常小心允许不安全的 http。您不想将该设置设置为 true。一切都应该通过 https,因为这样你的 headers 和 post body 将被加密。否则它们将被暴露,任何人基本上都可以窃取您的 ID 和秘密,然后继续发行有效的代币。所以,一路https。