c# - 即使发送了 token ,ASP.NET 身份也为空

标签 c# asp.net authentication asp.net-identity

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

基本部分工作正常。我有一个移动客户端,我可以在上面注册一个新用户。然后我可以登录并接收 token 。然后当我发出请求时, token 将在请求 header 中发送。一切正常。 我的问题是,如果我调用 [Authorize] 方法,我会收到 401 Unauthorized 错误,即使我发送了 token 。所以我删除了 [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=假;名称=空;声明:空

var token = Request.Headers.Authorization;

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

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

以下是我的部分代码: 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);
    }
}

Controller 方法:

#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);

    }

}

最佳答案

终于找到问题了。它是如此简单,以至于我无法相信我花了一个多星期来解决这个问题。

问题出在启动中。我只需在 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);

    }

}

关于c# - 即使发送了 token ,ASP.NET 身份也为空,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32039248/

相关文章:

asp.net - SignalR 内部如何工作 : client side

c# - 不记名 token 无效

java - 发现 nn/hadoop-kerberos@HADOOP-KERBEROS 不支持的 key 类型 (8)

c# - 将转换器应用于 Blend 中的数字时,设计 View 在 TextBlock 中显示 `System.Object`

c# - 为什么 C 语言在 if 语句中需要围绕简单条件的括号?

jquery - 如何隐藏空嵌套中继器?

c# - c#中是否有类似SQL IN语句的比较运算符

authentication - 使用 ember Octane 登录后刷新应用程序路由模型

c# - 为什么我的 Service Fabric 代码会锁定它自己的 PDB?

c# - 我应该如何在类和应用层之间传递数据?