ASP.NET 即使发送了令牌,身份也为空

ASP.NET Identity is null even the token is sent

对于我的论文项目,我必须在我的 ASP.NET 解决方案中实施 token-based(不记名)身份验证。我像 Taiseer Jouseh (http://bitoftech.net/2014/06/01/token-based-authentication-asp-net-web-api-2-owin-asp-net-identity) 那样实现了它。

基本部分工作正常。我有一个移动客户端,我可以在上面注册一个新用户。然后我可以登录并接收令牌。然后当我发出请求时,令牌在请求 Header 中发送。一切正常。 我的问题是,如果我调用 [Authorize] 方法,我会收到 401 Unauthorized 错误,即使我发送了令牌。所以我删除了 [Authorize] 注释来测试一些东西:

var z = User.Identity;
var t = Thread.CurrentPrincipal.Identity;
var y = HttpContext.Current.User.Identity;
var x = Request.GetOwinContext().Authentication.User.Identity;

在这里我总是得到相同的身份:AuthenticationType=null; IsAuthenticated=假;名称=空; Claims:empty

var token = Request.Headers.Authorization;

在这里我得到了正确的令牌。所以令牌是由请求发送的。

希望你能帮助我。我有令牌但没有身份。

以下是我的部分代码: OAuthServiceProvider:

public class SimpleAuthorizationServerProvider : OAuthAuthorizationServerProvider
{

    public async override Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context)
    {
        context.Validated();
    }

    // POST /token
    public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
    {

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

        var userManager = DependencyResolver.Current.GetService<UserManager<IdentityUser, int>>();

        IdentityUser user = await userManager.FindAsync(context.UserName, context.Password);

        if (user == null)
        {
            context.SetError("invalid_grant", "The user name or password is incorrect.");
            return;
        }

        var identity = await userManager.CreateIdentityAsync(user, context.Options.AuthenticationType);
        identity.AddClaim(new Claim("sub", context.UserName));
        identity.AddClaim(new Claim("role", "user"));
        context.Validated(identity);
    }
}

控制器方法:

#region GET /user/:id
[HttpGet]
[Route("{id:int:min(1)}")]
[ResponseType(typeof(UserEditDto))]
public async Task<IHttpActionResult> GetUser(int id)
{
    try
    {
        // tests
        var z = User.Identity;
        var t = Thread.CurrentPrincipal.Identity;
        var y = HttpContext.Current.User.Identity;
        var x = Request.GetOwinContext().Authentication.User.Identity;
        var token = Request.Headers.Authorization;

        User user = await _userManager.FindByIdAsync(id);
        if (user == null)
        {
            return NotFound();
        }

        Mapper.CreateMap<User, UserEditDto>();
        return Ok(Mapper.Map<UserEditDto>(user));
    }
    catch (Exception exception)
    {
        throw;
    }

}
#endregion

WebApiConfig:

public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        config.SuppressDefaultHostAuthentication();
        config.Filters.Add(new HostAuthenticationFilter("Bearer"));

        config.MapHttpAttributeRoutes();

        var corsAttr = new EnableCorsAttribute("*", "*", "*");
        config.EnableCors(corsAttr);

        config.Routes.MapHttpRoute(
             name: "DefaultApi",
             routeTemplate: "api/{controller}/{id}",
             defaults: new { id = RouteParameter.Optional }
        );
    }
}

启动:

[assembly: OwinStartup(typeof(Startup))]
public class Startup
{

    public void Configuration(IAppBuilder app)
    {
        HttpConfiguration config = new HttpConfiguration();
        var container = new UnityContainer();
        UnityConfig.RegisterComponents(container);
        config.DependencyResolver = new UnityDependencyResolver(container);
        //config.DependencyResolver = new UnityHierarchicalDependencyResolver(container);
        WebApiConfig.Register(config);
        app.UseWebApi(config);
        ConfigureOAuth(app);
    }

    public void ConfigureOAuth(IAppBuilder app)
    {
        OAuthAuthorizationServerOptions OAuthServerOptions = new OAuthAuthorizationServerOptions()
        {
            AllowInsecureHttp = true,
            TokenEndpointPath = new PathString("/token"),
            AccessTokenExpireTimeSpan = TimeSpan.FromDays(1),
            Provider = new SimpleAuthorizationServerProvider()
        };

        // Token Generation
        app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions());
        app.UseOAuthAuthorizationServer(OAuthServerOptions);

    }

}

我的猜测是令牌未从客户端正确发送。您发送的授权令牌前面是否带有 "Bearer" 前缀?

授权 Header 应该如下所示 -

Authorization:Bearer reNjoIUZBJHCMigQJHzCgMMVUyu4vg

在 chrome 开发人员工具网络选项卡中查看正在发送的内容。

终于找到问题了。太简单了,我简直不敢相信我花了一个多星期才解决这个问题。

问题出在启动中。我只需要在 app.UseWebApi(config);

之前调用 ConfigureOAuth(app);

所以正确的 Startup 看起来像

[assembly: OwinStartup(typeof(Startup))]
public class Startup
{

    public void Configuration(IAppBuilder app)
    {
        HttpConfiguration config = new HttpConfiguration();
        var container = new UnityContainer();
        UnityConfig.RegisterComponents(container);
        config.DependencyResolver = new UnityDependencyResolver(container);
        //config.DependencyResolver = new UnityHierarchicalDependencyResolver(container);
        WebApiConfig.Register(config);
        ConfigureOAuth(app);
        app.UseWebApi(config);
    }

    public void ConfigureOAuth(IAppBuilder app)
    {
        OAuthAuthorizationServerOptions OAuthServerOptions = new OAuthAuthorizationServerOptions()
        {
            AllowInsecureHttp = true,
            TokenEndpointPath = new PathString("/token"),
            AccessTokenExpireTimeSpan = TimeSpan.FromDays(1),
            Provider = new SimpleAuthorizationServerProvider()
        };

        // Token Generation
        app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions());
        app.UseOAuthAuthorizationServer(OAuthServerOptions);

    }

}