asp.net OAuth令牌错误401:未经授权

时间:2015-07-27 20:19:36

标签: asp.net asp.net-web-api access-token unauthorized

我正在使用ASP.NET Web API(C#)。我尝试实现基于令牌的身份验证。这是我的Startup.Auth类

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

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

        OAuthOptions = new OAuthAuthorizationServerOptions
        {
            TokenEndpointPath = new PathString("/Token"),
            Provider = new ApplicationOAuthProvider(PublicClientId, UserManagerFactory),

            AccessTokenExpireTimeSpan = TimeSpan.FromHours(2),
            AllowInsecureHttp = true
        };

     }

    public static OAuthAuthorizationServerOptions OAuthOptions { get; private set; }

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

    public static string PublicClientId { get; private set; }

    public void ConfigureAuth(IAppBuilder app)
    {
        app.UseCookieAuthentication(new CookieAuthenticationOptions());
        app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);
        app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);
        // Enable the application to use bearer tokens to authenticate users
        app.UseOAuthBearerTokens(OAuthOptions);
    /* login with third party login providers......*/
    }

我还有另一种发行令牌的方法

    public async Task<IHttpActionResult> Login(LoginModel model)
    /* some stuff here...*/
    if (hasRegistered)
            {
                identity = await UserManager.CreateIdentityAsync(user, OAuthDefaults.AuthenticationType);
                IEnumerable<Claim> claims = externalLogin.GetClaims();
                identity.AddClaims(claims);
                Authentication.SignIn(identity);
            }

        AuthenticationTicket ticket = new AuthenticationTicket(identity, new AuthenticationProperties());
        var currentUtc = new Microsoft.Owin.Infrastructure.SystemClock().UtcNow;
        ticket.Properties.IssuedUtc = currentUtc;
        ticket.Properties.ExpiresUtc = currentUtc.Add(TimeSpan.FromHours(2));
        var accessToken = Startup.OAuthOptions.AccessTokenFormat.Protect(ticket);


        // Create the response building a JSON object that mimics exactly the one issued by the default /Token endpoint
        JObject token = new JObject(
            new JProperty("userName", user.UserName),
            new JProperty("id", user.Id),
            new JProperty("access_token", accessToken),
            new JProperty("token_type", "bearer"),
            new JProperty("expires_in", TimeSpan.FromHours(2).TotalSeconds.ToString()),
            new JProperty(".issued", currentUtc.ToString("ddd, dd MMM yyyy HH':'mm':'ss 'GMT'")),
            new JProperty(".expires", currentUtc.Add(TimeSpan.FromHours(2)).ToString("ddd, dd MMM yyyy HH:mm:ss 'GMT'"))
        );
        return Ok(token);
    }

两种方法都有效。但是,如果我将[Authorize]放在控制器中并使用使用第二种方法(登录)发出的令牌,我总是得到“此请求已拒绝授权”错误。为什么会这样?我究竟做错了什么?

1 个答案:

答案 0 :(得分:1)

看起来您在身份验证后成功获取令牌。要访问资源(具有authorize属性的apicontroller),您需要在Authorization标头中传递承载令牌(前缀为&#39; Bearer&#39;)。示例:&#39; Bearer [Tokenstring]&#39;。

您可以在首选浏览器上下载restclient(休息控制台,邮递员等)工具进行测试。尝试正常的GET请求并放置“承载”[令牌]&#39;在授权标头字段中。我希望这会有所帮助。