【问题标题】:Current user in owin authenticationowin 身份验证中的当前用户
【发布时间】:2014-09-25 19:21:12
【问题描述】:

我开始为移动应用程序构建 Web api,但我很难实现身份验证。我使用 Bearer,虽然一切都应该没问题,但我无法从控制器中的操作中获取当前用户。 HttpContext.Current.User.Identity.Name 为空(同样是 HttpContext.Current.User.Identity.GetUserId() 的结果)。以下是一些重要的代码:

Startup.cs:

    public partial class Startup
    {
        public void Configuration(IAppBuilder app)
        {
            var config = new HttpConfiguration();
            ConfigureAuth(app);
            WebApiConfig.Register(config);
            app.UseWebApi(config);
        }
    }

Startup.Auth.cs

public partial class Startup
{
        static Startup()
        {
            OAuthOptions = new OAuthAuthorizationServerOptions
            {
                TokenEndpointPath = new PathString("/token"),
                Provider = new ApplicationOAuthProvider(),
                AccessTokenExpireTimeSpan = TimeSpan.FromDays(1),
                AllowInsecureHttp = true
            };

            OAuthBearerOptions = new OAuthBearerAuthenticationOptions();
        }

        public static OAuthAuthorizationServerOptions OAuthOptions { get; private set; }
        public static OAuthBearerAuthenticationOptions OAuthBearerOptions { get; private set; }


        public static string PublicClientId { get; private set; }

        public void ConfigureAuth(IAppBuilder app)
        {
            app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions
            {
                AccessTokenProvider = new AuthenticationTokenProvider()
            });
            app.UseOAuthBearerTokens(OAuthOptions);

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

        }
}

ApplicationOAuthProvider.cs:

        public override Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context)
        {

            string clientId, clientSecret;

            if (!context.TryGetBasicCredentials(out clientId, out clientSecret))
            {
                return SetErrorAndReturn(context, "client error", "");
            }

            if (clientId == "secret" && clientSecret == "secret")
            {
                context.Validated();
                return Task.FromResult<object>(null);
            }

            return SetErrorAndReturn(context, "client error", "");
        }

        public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
        {

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

            using (AuthRepository _repo = new AuthRepository())
            {
                IdentityUser user = await _repo.FindUser(context.UserName, context.Password);

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

            var identity = new ClaimsIdentity(context.Options.AuthenticationType);
            identity.AddClaim(new Claim("sub", context.UserName));
            identity.AddClaim(new Claim("role", "user"));

            context.Validated(identity);
        }


        public override Task TokenEndpoint(OAuthTokenEndpointContext context)
        {
            foreach (KeyValuePair<string, string> property in context.Properties.Dictionary)
            {
                context.AdditionalResponseParameters.Add(property.Key, property.Value);
            }

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

AuthRepository.cs:

public class AuthRepository : IDisposable
    {
        private readonly AuthContext _ctx;

        private readonly UserManager<IdentityUser> _userManager;

        public AuthRepository()
        {
            _ctx = new AuthContext();
            _userManager = new UserManager<IdentityUser>(new UserStore<IdentityUser>(_ctx));
        }

        public async Task<IdentityResult> RegisterUser(UserModel userModel)
        {
            var user = new IdentityUser
            {
                UserName = userModel.UserName
            };

            var result = await _userManager.CreateAsync(user, userModel.Password);

            return result;
        }

        public async Task<IdentityUser> FindUser(string userName, string password)
        {
            IdentityUser user = await _userManager.FindAsync(userName, password);
            return user;
        }

        public void Dispose()
        {
            _ctx.Dispose();
            _userManager.Dispose();

        }
    }

AuthContext.cs:

public class AuthContext : IdentityDbContext<IdentityUser>
    {
        public AuthContext()
            : base("AuthContext")
        {

        }
    }

最后是 ValuesController.cs:

[Authorize]
public class ValuesController : ApiController
{

    public IEnumerable<string> Get()
    {
        return new String[] {HttpContext.Current.User.Identity.Name, HttpContext.Current.User.Identity.GetUserId(),ClaimsPrincipal.Current.Identity.Name};
    }
}

当我执行此操作时,我得到 null 3 次。尽管如此,整个身份验证过程似乎都很好——只有当我发送一个好的令牌时,我才能访问。有人知道这里有什么问题吗?

【问题讨论】:

  • 您在return new String[] { HttpContext... 上设置了断点吗?第一个空值在哪里?
  • 最后一个非空值是Identity(所以我没有收到错误,但返回值为空)
  • GetUserId() 也为空吗?
  • 是的,这个方法也给我null。
  • 我没有看到你的登录方法,你应该被称为FormsAuthentication.SetAuthCookie(username, true);。参考。 stackoverflow.com/questions/1056487/…

标签: c# asp.net-mvc owin


【解决方案1】:

在验证用户名密码后添加声明后,在方法 GrantResourceOwnerCredentials 上,您需要添加此声明:

identity.AddClaim(new Claim(ClaimTypes.Name, context.UserName));

通过这样做,当您在受保护的控制器中调用 User.Identity.Name 时,将填充 UserId。 希望这能解决您的问题。

【讨论】:

  • 不幸的是,它没有帮助。我仍然为空。我不确定我是否理解受保护控制器的部分。我所做的只是在 identity.AddClaim(new Claim("role", "user"));
  • 我的意思是受保护的控制器是一个带有 [Authorize] 的控制器属性,如果您检查了值 User.Identity.IsAuthenticated 是否设置为 true 并且 User.Identity.Name 在添加此声明后始终为空?
  • 还要感谢以上解决方案!只是为了澄清 user55 说了什么..您必须在提供程序中添加声明,然后重新登录以创建新令牌,然后才能看到更改(我正在使用现有令牌刷新页面并想知道为什么我不能'看不到用户名,哈)
猜你喜欢
  • 2017-03-06
  • 1970-01-01
  • 2015-09-23
  • 2023-04-05
  • 1970-01-01
  • 2014-09-15
  • 2015-07-18
  • 2020-11-15
  • 2023-03-16
相关资源
最近更新 更多