【问题标题】:ASP.NET WEB API 2 OWIN Authentication unsuported grant_TypeASP.NET WEB API 2 OWIN 身份验证不支持 grant_Type
【发布时间】:2014-03-25 03:17:57
【问题描述】:

您好,我正在尝试在我的 ASP.NET Web API 2 项目中设置 OAuth 持有者令牌身份验证。 我有两个项目,一个是 WEB API 项目,另一个是 SPA 项目。

这是我到目前为止所做的:

我已经创建了 OWIN 启动类:

[assembly: OwinStartup(typeof(CodeArt.WebApi.App_Start.Startup))]

namespace CodeArt.WebApi.App_Start

{
    public class Startup
    {
        static Startup()
        {
            PublicClientId = "self";

        UserManagerFactory = () => new UserManager<UserModel>(new UserStore<UserModel>());

        OAuthOptions = new OAuthAuthorizationServerOptions {
            TokenEndpointPath = new PathString("/Token"),
            Provider = new OAuthAuthorizatonServer(PublicClientId, UserManagerFactory),
            AuthorizeEndpointPath = new PathString("/api/Account/ExternalLogin"),
            AccessTokenExpireTimeSpan = TimeSpan.FromDays(14),
            AllowInsecureHttp = true
        };
    }

    public static OAuthAuthorizationServerOptions OAuthOptions { get; private set; }

    public static Func<UserManager<UserModel>> UserManagerFactory { get; set; }

    public static string PublicClientId { get; private set; }
    public void Configuration(IAppBuilder app)
    {
        ConfigureAuth(app);
    }

    public void ConfigureAuth(IAppBuilder app)
    {
        app.UseCookieAuthentication(new CookieAuthenticationOptions());
        app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalBearer);
        app.UseOAuthBearerTokens(OAuthOptions);
    }
}

我已将 Web API 配置为仅使用不记名令牌身份验证:

    private static void ConfigureBearerTokenAuthentication(HttpConfiguration config)
    {
        config.SuppressDefaultHostAuthentication();
        config.Filters.Add(new HostAuthenticationFilter(Startup.OAuthOptions.AuthenticationType));

    }

我已配置 WEB API 以支持 CORS:

    private static void ConfigureCrossOriginResourseSharing(HttpConfiguration config)
    {
        var cors = new EnableCorsAttribute("*", "*", "*");
        config.EnableCors(cors);
    }

我已经创建了 OAuthAuthorizationServerProvider 类。从这个类我只设法让我的代码调用这个方法:

   public override Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context)
    {
        if(context.ClientId == null)
        {
            context.Validated();
        }

        return Task.FromResult<object>(null);
    }

其中的 if 条件总是被执行。

在我的水疗项目中,我有以下内容:

这是我的视图模型:

 var vm = {
        grant_type: "password",
        userName: ko.observable(),
        password: ko.observable()
};

当登录按钮被点击时,我调用这个函数:

     var http = {
          post:function(url, data) {
             return $.ajax({
                url: url,
                data: data,
                type: 'POST',
                contentType: 'application/json',
                dataType: 'jsonp'
            });
        }
     }

function loginClick() {
        var model = ko.mapping.toJS(vm.loginModel);
        var rez = $.param(model);

        http.post("http://localhost:3439/Token", rez)
            .done(function (data) {
                console.log(data);
            })
            .fail(function(eror, stuff, otherstuff) {
                console.log(eror);
                console.log(stuff);
                console.log(otherstuff);
            });
    }

我第一次尝试将帖子调用 dataType 设置为 json,但出现以下错误:

OPTIONS ...:3439/Token 400(错误请求)jquery.js:7845

OPTIONS ...:3439/Token No 'Access-Control-Allow-Origin' 请求的资源上存在标头。起源 '...:3304' 因此不允许访问。 jquery.js:7845

XMLHttpRequest 无法加载 ...3439/Token。不 请求中存在“Access-Control-Allow-Origin”标头 资源。因此不允许使用原点“...3304” 访问。

三个点代表http://localhost。

第二次我将它的数据类型设置为 jsonp,我得到了一个错误,指出不支持“unsupported_grant_type”。

这两个调用都是我上面提到的 ValidateClientAuthentication ,但它们都作为失败的请求被发回。

现在我猜测问题与我如何发送数据而不是 grand_type 更相关,因为 Visual Studion 中的 SPA 模板集的授权类型为 grant_type: "password",就像我做的那样。

我还读到我必须序列化数据而不是在 json 中发送它才能在这里工作,这是发送的确切 json 序列化数据: "grant_type=password&userName=aleczandru&password=happynewYear&moduleId=models%2FappPostModels%2FloginModel"

Durandal Framework 将模型 id 属性设置为我的 SPA 模板中的所有对象。

谁能告诉我我做错了什么?过去两天我一直在努力解决这个问题?

【问题讨论】:

    标签: asp.net-web-api asp.net-web-api2


    【解决方案1】:

    将以下代码行添加到GrantResourceOwnerCredentials,这会将标头添加到响应中。

    context.OwinContext.Response.Headers.Add("Access-Control-Allow-Origin", new[] { "*" });
    

    有关更多信息,请参阅: web-api-2-0-cors-and-individual-account-identity

    【讨论】:

    • 有趣的是,我认为在 WEB.API 级别启用 CORS 就足够了
    • 我创建了一个代码项目教程,介绍如何将新的 Web API 2 与 AngularJS 客户端 codeproject.com/Articles/742532/… 一起使用。希望能提供更多细节。
    • 我刚试过这个没有任何成功,我仍然得到错误。还有其他建议吗?
    • 您能否提供更多详细信息,您是否尝试过下载我提到的教程中的项目? link
    • 我找到了另一个解决方案,方法是使用 app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);
    【解决方案2】:

    就像 Robin Karlsson 所说,你应该使用:

    app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);
    

    在您的启动配置中。

    并确保它是唯一的 cors 语句(不要混合使用)和 Startup 中的第一个语句。

    【讨论】:

    • 确保安装各种跨域支持的nuget包
    • 我已经尝试在全球范围内(通过 OWIN app.UseCors 如你所说)和单独的 OWIN 和 Web API 策略启用 CORS。我的 Policy Resolver 正在正确处理“/token” URL,但我仍然没有看到来自服务器的 Access-Control-Allow-Origin 响应。我不想在 web.config 中全局添加标头。发生了什么事?
    • 如果服务器出现错误,某些浏览器(如 chrome)会给出允许访问的来源错误。我有时会在开发时得到它们。你确定没有其他事情发生吗?尝试切换所有身份验证并访问简单的测试控制器。检查您的日志和跟踪。
    猜你喜欢
    • 2014-08-24
    • 1970-01-01
    • 1970-01-01
    • 2013-11-25
    • 2015-01-30
    • 2016-12-31
    • 2014-07-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多