【问题标题】:Use [Authorize] attribute with user's email对用户的电子邮件使用 [Authorize] 属性
【发布时间】:2016-02-07 14:41:38
【问题描述】:

我已经看到 [Authorize] 属性采用像 [Authorize("User=Alice, Bob")] 这样的 AuthorizeAttribute.User 属性(我猜Alice/Bob 是用户名?)。但是,在我的应用程序中,我注册的只是用户的电子邮件地址。

[Authorize("User=...")] 是否占用其他属性?它可以接收电子邮件吗(并使用[Authorize("User=alice@example.org, bob@example.org")]?毫不奇怪,MSDN page 不是很有帮助。

这是内置的功能,还是我必须实现自己的自定义 Authorize 属性?在我上面链接的非常少的 MSDN 页面之后,是否有关于 Authorize 属性的完整参数列表的任何文档?

【问题讨论】:

  • Authorizez 不在乎用户名是登录名还是电子邮件。
  • 如果您使用开箱即用的身份提供商,电子邮件就是用户名。
  • 您可能会更好地考虑为“角色”而不是“名字”执行此操作。您的角色可以是管理员、标准、增强等,您可以以相同的方式简单地分配角色。您将如何处理必须处理多个不同名字的人的控制器操作。

标签: c# asp.net .net asp.net-mvc asp.net-web-api


【解决方案1】:

我认为这里没有区别...“james.doe@example.com”是一个字符串,就像“James Doe”是一个字符串一样,两者都用于 User 属性。

也就是说,如果您想拥有自己的属性,例如UserName,那么只需从Authorize 属性派生一个新的 Attribute 类,并使用您自己的授权逻辑添加您自己的属性。

资源:


示例:自定义授权属性


HomeController.cs

public class HomeController : Controller
{
    [CustomAuthorize(FirstNames = "Aydin")]
    public ActionResult Index()
    {
        return View();
    }
}

ApplicationUser.cs ||用户.cs

public class User : IdentityUser
{
    public string FirstName { get; set; }
    
    public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<User> manager)
    {
        ClaimsIdentity userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie);
        userIdentity.AddClaim(new Claim("FirstName", this.FirstName));
        return userIdentity;
    }
}

CustomAuthorizeAttribute.cs

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true)]
public class CustomAuthorizeAttribute : FilterAttribute, IAuthorizationFilter
{
    private static readonly char[] SplitParameter = new char[1] {','};
    private string firstNames;
    private string[] firstNamesSplit = new string[0];

    public string FirstNames 
    {
        get { return this.firstNames ?? string.Empty; }
        set
        {
            this.firstNames = value;
            this.firstNamesSplit = SplitString(value);
        }
    }

    /// <summary> Called when a process requests authorization. </summary>
    public virtual void OnAuthorization(AuthorizationContext filterContext)
    {
        if (filterContext == null)
        {
            throw new ArgumentNullException("filterContext");
        }

        if (OutputCacheAttribute.IsChildActionCacheActive(filterContext))
        {
            throw new InvalidOperationException("Cannot use with a ChildAction cache");
        }

        if (filterContext.ActionDescriptor.IsDefined(typeof (AllowAnonymousAttribute), true) ||
            filterContext.ActionDescriptor.ControllerDescriptor.IsDefined(typeof (AllowAnonymousAttribute), true))
        {
            return;
        }

        if (this.AuthorizeCore(filterContext.HttpContext))
        {
            HttpCachePolicyBase cache = filterContext.HttpContext.Response.Cache;
            cache.SetProxyMaxAge(new TimeSpan(0L));
            cache.AddValidationCallback(this.CacheValidateHandler, null);
        }
        else
            this.HandleUnauthorizedRequest(filterContext);
    }

    /// <summary> When overridden, provides an entry point for custom authorization checks. </summary>
    protected virtual bool AuthorizeCore(HttpContextBase httpContext)
    {
        if (httpContext == null) throw new ArgumentNullException("httpContext");

        IPrincipal user = httpContext.User;
        if (!user.Identity.IsAuthenticated) return false;

        string claimValue = ClaimsPrincipal.Current.FindFirst("FirstName").Value;
        return this.firstNamesSplit.Length <= 0 ||
               this.firstNamesSplit.Contains(claimValue, StringComparer.OrdinalIgnoreCase);
    }

    private void CacheValidateHandler(HttpContext context, object data, ref HttpValidationStatus validationStatus)
    {
        validationStatus = this.OnCacheAuthorization(new HttpContextWrapper(context));
    }

    /// <summary> Processes HTTP requests that fail authorization. </summary>
    protected virtual void HandleUnauthorizedRequest(AuthorizationContext filterContext)
    {
        filterContext.Result = new HttpUnauthorizedResult();
    }

    /// <summary>  Called when the caching module requests authorization. </summary>
    /// <returns>  A reference to the validation status.  </returns>
    protected virtual HttpValidationStatus OnCacheAuthorization(HttpContextBase httpContext)
    {
        if (httpContext == null) throw new ArgumentNullException("httpContext");
        return !this.AuthorizeCore(httpContext)
            ? HttpValidationStatus.IgnoreThisRequest
            : HttpValidationStatus.Valid;
    }

    private string[] SplitString(string original)
    {
        if (string.IsNullOrEmpty(original)) return new string[0];

        return original.Split(SplitParameter)
            .Select(splitItem => new
            {
                splitItem,
                splitItemTrimmed = splitItem.Trim()
            })
            .Where (value => !string.IsNullOrEmpty(value.splitItemTrimmed))
            .Select(value => value.splitItemTrimmed).ToArray();
    }
}

【讨论】:

  • 是亲身体验过的,不过测试起来很简单,你的目标是拥有自己的房产吗?或者利用 Microsoft 已经实现的功能
  • 没有。我对那里的文档很少感到沮丧,并希望了解此处的 User 参数并为我的用例使用最佳实现。
  • 我刚开始时发现 PluralSight 的视频很有帮助,这个特别的视频可能会提供一些见解...PluralSight MVC4 Security-Authorize 和这个PluralSight MVC5 Security-Authorize。也跳过 MSDN ......这就是你要找的东西 ASP.NET MVC
  • Aydin,你有关于 Authorize 如何查找 User 对象的任何实现细节吗?如果你这样做,你能把它添加到你的答案中吗?
  • 我实际上刚刚离开家用手机打字......我可以在几个小时后回到家时添加它......同时我可以给你一个快速的概述。当您首次对自己进行身份验证时,身份框架会加密您的凭据和角色,并将它们作为 cookie 存储在客户端计算机上。当您下次再次访问您的网站时,您的操作会执行其到 auth 过滤器的路由。过滤器检查存储在 cookie 中的凭据是否与 auth 属性中指定的约束匹配
猜你喜欢
  • 2015-09-21
  • 1970-01-01
  • 2022-12-05
  • 2012-02-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多