【问题标题】:Retrieve User from LDAP using ASP Membership使用 ASP 成员资格从 LDAP 检索用户
【发布时间】:2015-10-07 14:48:43
【问题描述】:

我的公司正在使用 LDAP 对其用户进行身份验证。我有登录部分工作,但现在我需要一种登录后我们可以引用用户的方式。我尝试了多种方法,但都没有奏效。

这是我用来登录的代码:

var x = Membership.Provider;

if (Membership.ValidateUser(model.UserName, model.Password))
{
    FormsAuthentication.SetAuthCookie(model.UserName, model.RememberMe);

    if (Url.IsLocalUrl(returnUrl) && returnUrl.Length > 1 && returnUrl.StartsWith("/")
    && !returnUrl.StartsWith("//") && !returnUrl.StartsWith("/\\"))
    {
        return Redirect(returnUrl);
    }
    else
    {
        string userId = Membership.GetUser().ProviderUserKey.ToString();
        return RedirectToAction("Index", "Home");
    }
}

在这一行:

string userId = Membership.GetUser().ProviderUserKey.ToString();

我收到一个错误:

参数“用户名”不能为空。

我也从这里尝试了一些选项:

How can I access UserId in ASP.NET Membership without using Membership.GetUser()?

喜欢这个:

MembershipUser CurrentUser = Membership.GetUser(User.Identity.Name);

我得到了同样的错误

对于任何想知道的人,iamtooamazing 建议如下:

string userId = Membership.GetUser(model.UserName).ProviderUserKey.ToString();

这将在这种方法中起作用。但是,我将无法在解决方案的其他任何地方使用它。我需要可以在所有控制器(以及其中的方法)中使用的东西

使用此代码:

string user = ((CustomIdentity)User.Identity).UserId;

我在该行收到此错误:

无法转换类型的对象 'System.Security.Principal.GenericIdentity' 键入 'STCAuthentication.Models.CustomIdentity'。

这是我的代码的当前状态:

[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public ActionResult Login(LoginModel model, string returnUrl)
{
    if (ModelState.IsValid)
    {

        var x = Membership.Provider;
        if (Membership.ValidateUser(model.UserName, model.Password))
        {

            if (Url.IsLocalUrl(returnUrl) && returnUrl.Length > 1 && returnUrl.StartsWith("/")
                && !returnUrl.StartsWith("//") && !returnUrl.StartsWith("/\\"))
            {
                return Redirect(returnUrl);
            }
            else
            {
                string user = ((CustomIdentity)User.Identity).UserId;
                return RedirectToAction("Index", "Home");
            }
        }
        else
        {
            ModelState.AddModelError("", "The user name or password provided is incorrect.");
        }
    }

    // If we got this far, something failed, redisplay form
    return View(model);
}

【问题讨论】:

  • 你为什么不能这样做:string userId = Membership.GetUser(model.UserName).ProviderUserKey.ToString();?
  • @iamtooamazing 但这仅适用于此方法。在我的解决方案的任何其他地方我会做什么?
  • @iamtooamazing 你有什么想法吗?
  • @djblois 您在尝试投射身份时是否已经通过身份验证?
  • @SílvioN.,是的,我已经通过了身份验证

标签: c# asp.net-mvc asp.net-membership


【解决方案1】:

这将在这种方法中起作用。但是,我将无法使用 解决方案中的其他任何地方。我需要一些有用的东西 所有的控制器(以及其中的方法)

如果您创建一个自定义身份来存储您的用户 ID,那会怎样?

public class CustomIdentity : IIdentity
{
    private IIdentity Identity { get; set; }
    public string UserId { get; private set; }

    public string AuthenticationType { get { return Identity.AuthenticationType; } }
    public bool IsAuthenticated { get { return Identity.IsAuthenticated; } }
    public string Name { get { return Identity.Name; } }

    public CustomIdentity(IIdentity identity)
    {
        Identity = identity;
        UserId = Membership.GetUser(identity.Name).ProviderUserKey.ToString();
    }
}

同时创建一个 CustomPrincipal,

public class CustomPrincipal : IPrincipal
{
    private IPrincipal Principal;
    public IIdentity Identity { get; private set; }
    public bool IsInRole(string role) { return Principal.IsInRole(role); }

    public CustomPrincipal(IPrincipal principal)
    {
        Principal = principal;
        //this force the load of the userid
        Identity = new CustomIdentity(principal.Identity);
    }
}

然后在 Global.asax 中设置

protected void Application_PreRequestHandlerExecute(object sender, EventArgs e)
{
        if (Request.IsAuthenticated)
        {
            var principal = new CustomPrincipal(HttpContext.Current.User);
            HttpContext.Current.User = principal;
        }
}

你可以像这样访问你的 UserId

((CustomIdentity)User.Identity).UserId //In Controllers
((CustomIdentity)HttpContext.Current.User.Identity).UserId //Inside classes

这就是你要找的吗?

【讨论】:

  • 看起来非常接近。使用 [Authorize(Roles = "Client, Administrator")] 时会怎样?
  • 现在呢?它现在将默认主体传递给构造函数,以便主体对象使用本机 IsInRole 方法...
  • 谢谢你,我会解决这个问题并回复你。
  • 但如果我没记错的话,[Authorize] 属性的使用将使用您的默认/自定义 RoleProvider,它不会干扰 customprincipal 或 customidentity...
  • 嗨 Silvio,我已经用收到的错误更新了它。