asp.net中的form authentication,windows auth,openId/oAuth

form+authentication:

这篇转载自:https://www.cnblogs.com/yujihaia/p/7367559.html

使用Authorize特性进行身份验证


  通常情况下,应用程序都是要求用户登录系统之后才能访问某些特定的部分。在ASP.NET MVC中,可以通过使用Authorize特性来实现,甚至可以对整个应用程序全局使用Authorize特性。

Authorize的用法

本节以一个添加产品的示例来说明Authorize的使用方法。首先,创建Product类、添加属性(如下所示)并创建ProductsController(MVC5 Controller with views,using Entity Framework)。

public class Product
{
    //产品编号
    public int Id { get; set; }
    //产品名称
    public string ProductName { get; set; }
    //产品描述
    public string Description { get; set; }
    //产品价格
    public decimal Price { get; set; }
}

运行程序,将Url定位到/Products/Create,添加如下产品。

此时收到用户需求,必须是已经登录的用户才可以添加产品,如匿名用户请求访问产品创建页面,则直接定位到登录界面。修改ProdutsController,只需要在Create动作上添加Authorize特性。

    [Authorize]
    public ActionResult Create()
    {
        return View();
    }

这时,我们在未登录状态下请求访问产品创建页面时,系统自动跳转到登录页面。下面,我们来看一看Authorize特性的的工作原理。当用户请求一个Action时,会调用OnAuthorization方法:

    public virtual void OnAuthorization(AuthorizationContext filterContext)
    {
        if (filterContext == null)
        {
            throw new ArgumentNullException("filterContext");
        }

        if (OutputCacheAttribute.IsChildActionCacheActive(filterContext))
        {
            // If a child action cache block is active, we need to fail immediately, even if authorization
            // would have succeeded. The reason is that there's no way to hook a callback to rerun
            // authorization before the fragment is served from the cache, so we can't guarantee that this
            // filter will be re-run on subsequent requests.
            throw new InvalidOperationException(MvcResources.AuthorizeAttribute_CannotUseWithinChildActionCache);
        }

        bool skipAuthorization = filterContext.ActionDescriptor.IsDefined(typeof(AllowAnonymousAttribute), inherit: true)
                                 || filterContext.ActionDescriptor.ControllerDescriptor.IsDefined(typeof(AllowAnonymousAttribute), inherit: true);

        if (skipAuthorization)
        {
            return;
        }

        if (AuthorizeCore(filterContext.HttpContext))
        {
            // ** IMPORTANT **
            // Since we're performing authorization at the action level, the authorization code runs
            // after the output caching module. In the worst case this could allow an authorized user
            // to cause the page to be cached, then an unauthorized user would later be served the
            // cached page. We work around this by telling proxies not to cache the sensitive page,
            // then we hook our custom authorization code into the caching mechanism so that we have
            // the final say on whether a page should be served from the cache.

            HttpCachePolicyBase cachePolicy = filterContext.HttpContext.Response.Cache;
            cachePolicy.SetProxyMaxAge(new TimeSpan(0));
            cachePolicy.AddValidationCallback(CacheValidateHandler, null /* data */);
        }
        else
        {
            HandleUnauthorizedRequest(filterContext);
        }
    }

skipAuthorization代表是否跳过验证,如果Action或Controller定义了AllowAnonymous特性,则跳过验证。若不跳过验证,则会判断AuthorizeCore方法的执行结果,再来看看AuthorizeCore方法的源码:

    protected virtual bool AuthorizeCore(HttpContextBase httpContext)
    {
        if (httpContext == null)
        {
            throw new ArgumentNullException("httpContext");
        }

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

        if (_usersSplit.Length > 0 && !_usersSplit.Contains(user.Identity.Name, StringComparer.OrdinalIgnoreCase))
        {
            return false;
        }

        if (_rolesSplit.Length > 0 && !_rolesSplit.Any(user.IsInRole))
        {
            return false;
        }

        return true;
    }

如果用户没有登录,则返回False;如果用户组长度大于0且不包括当前用户,则返回False;如果授权角色长度大于0且不包含当前用户,返回False;否则返回True 。

★Authorize特性不仅可以用在Action上,同样可以使用在Controller上

全局授权过滤器

  对于大部分网站而言,基本上整个应用程序都需要身份验证,当然我们不可能在每个控制器上添加Authorize特性。此时,把AuthorizeAttribute配置为全局过滤器,并使用AllowAnonymous特性来允许匿名访问某些控制器或方法。修改App_Start/FilterConfig.cs文件中的RegisterGlobalFilters方法:

    public static void RegisterGlobalFilters(GlobalFilterCollection filters)
    {
        filters.Add(new AuthorizeAttribute());
        filters.Add(new HandleErrorAttribute());
    }

注意,在AccountController中的Login方法,系统已经帮我们添加了AllowAnonymous特性,不然是无法正常登陆的。

    [AllowAnonymous]
    public ActionResult Login(string returnUrl)
    {
        ViewBag.ReturnUrl = returnUrl;
        return View();
    }

 

授权


使用Authorize特性限定用户或角色的访问

  目前为止,已经介绍了使用Authorize特性禁止匿名用户访问控制器或方法。同样的,我们也可以使用Authorize特性来限定特定用户或角色的访问。上一节中的示例,新增只有Administrator角色用户才能够编辑产品的功能。

    [Authorize(Roles ="Administrator")]
    public ActionResult Edit(int? id)
    {
        if (id == null)
        {
            return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
        }
        Product product = db.Products.Find(id);
        if (product == null)
        {
            return HttpNotFound();
        }
        return View(product);
    }

当然,我们也可以通过指定用户的方式来限定访问:

    [Authorize(Users = "Jack,Mike,July")]
    public ActionResult Edit(int? id)
    {
        if (id == null)
        {
            return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
        }
        Product product = db.Products.Find(id);
        if (product == null)
        {
            return HttpNotFound();
        }
        return View(product);
    }
----------------------------------------------------------------------------------------------------------------

ASP.NET MVC下判断用户登录和授权状态方法

原文链接:https://cloud.tencent.com/developer/article/1342190

在我们日常开发的绝大多数系统中,都涉及到管理用户的登录和授权问题。登录功能(Authentication),针对于所有用户都开放;而授权(Authorization),则对于某种用户角色才开放。

在asp.net mvc中,微软虽然已经帮助开发者构建了ASP.NET Identity这样强大的验证授权框架,但是如果想定制更多的逻辑功能的话,还得自己动动手。

根据日常的开发经验,我总结了大概下面2种方法:

继承Controller:

a) 在我最早的时候,比较单纯,也许是从WebForm那里学来的招式,我并没有细读Controller里的所有方法,所以在派生类里自己添加了验证方法,然后在每个Action方法里调用。此方法现在看来有些蛋疼...

派生类如下:

public class AuthenticationControllor : Controller
{
    public bool Validate()
    {
        if (Session["username"] == null)
            return false;
        else
            return true;
    }

    public ActionResult RedirectLogin(bool redirect = true)
    {
        if (redirect)
            return RedirectToAction("Login", "Home", new { from = Request.Url.ToString() });
        else
            return RedirectToAction("Login", "Home");
    }
}

使用类如下:

public class HomeController : AuthenticationControllor
{
    public ActionResult Index()
    {
        if (!Validate())
            return RedirectLogin();
 
        return View();
    }
}

b) 后来学习了很多人的代码后,发现在Controller里有一个OnActionExecuting方法,此方法是在Action之前执行的,非常方便。

派生类如下:

public class AuthenticationControllor : Controller
{
    protected override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        if (filterContext.HttpContext.Session["username"] == null)
            filterContext.Result = new RedirectToRouteResult("Login", new RouteValueDictionary { { "from", Request.Url.ToString() } });
            
        base.OnActionExecuting(filterContext);
    }
}

使用类如下:

// 不需要多写任何逻辑代码就能判断是否登录并跳转
public class HomeController : AuthenticationControllor
{
    public ActionResult Index()
    { 
        return View();
    }
}

继承ActionFilterAttribute:

由于继承Controller方法不太适合一个Controller下的有些Action需要登录有些Action不需要登录的场景,所以针对每个Action写一个统一的特性会更好一些。

ActionFilterAttribute里也有OnActionExecuting方法,跟Controller一样, 同是抽象实现了IActionFilter接口。

派生类如下:

// 登录认证特性
public class AuthenticationAttribute : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        if (filterContext.HttpContext.Session["username"] == null)
            filterContext.Result = new RedirectToRouteResult("Login", new RouteValueDictionary { { "from", Request.Url.ToString() } });
            
        base.OnActionExecuting(filterContext);
    }
}

使用方法如下:

public class HomeController : Controller 
{ 
    [Authentication] 
    public ActionResult Index()
    {
        return View();
    }
}

如果你想针对整个MVC项目的所有Action都使用此过滤器,步骤如下:

a) 确保Global.asax.csApplication_Start方法中包含如下第8行

public class MvcApplication : System.Web.HttpApplication
{
    protected void Application_Start()
    {
        AreaRegistration.RegisterAllAreas();

        WebApiConfig.Register(GlobalConfiguration.Configuration);
        FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
        RouteConfig.RegisterRoutes(RouteTable.Routes);
    }
}

b) 在FilterConfig.cs文件中注册相应的特性过滤器:

public class FilterConfig
{
    public static void RegisterGlobalFilters(GlobalFilterCollection filters)
    {
        filters.Add(new HandleErrorAttribute());
        filters.Add(new AuthenticationAttribute());
    }
}

推荐大家使用第2种过滤器的方法实现认证和授权。

https://www.cnblogs.com/yujihaia/p/7367559.html

posted @ 2021-12-19 23:06  vba是最好的语言  阅读(95)  评论(0)    收藏  举报