我正在使用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]放在控制器中并使用使用第二种方法(登录)发出的令牌,我总是得到“此请求已拒绝授权”错误。为什么会这样?我究竟做错了什么?
答案 0 :(得分:1)
看起来您在身份验证后成功获取令牌。要访问资源(具有authorize属性的apicontroller),您需要在Authorization标头中传递承载令牌(前缀为&#39; Bearer&#39;)。示例:&#39; Bearer [Tokenstring]&#39;。
您可以在首选浏览器上下载restclient(休息控制台,邮递员等)工具进行测试。尝试正常的GET请求并放置“承载”[令牌]&#39;在授权标头字段中。我希望这会有所帮助。