简体   繁体   English

针对同一应用程序中的WebAPI的MVC和OAuth的Cookie身份验证

[英]Cookie authentication for MVC and OAuth for WebAPI in the same app

I have an asp.net application that has both MVC controllers and WebAPI controllers. 我有一个asp.net应用程序,它同时具有MVC控制器和WebAPI控制器。

For cookie authentication I use app.UseCookieAuthentication(... middleware with DefaultAuthenticationTypes.ApplicationCookie authentication type. 对于cookie身份验证,我使用app.UseCookieAuthentication(...中间件与DefaultAuthenticationTypes.ApplicationCookie身份验证类型。

For OAuth I use app.UseOAuthBearerTokens(... middleware. 对于OAuth,我使用app.UseOAuthBearerTokens(...中间件。

For MVC routes I have used AuthorizeAttribute as global to prevent anonymous access. 对于MVC路由,我使用AuthorizeAttribute作为全局来阻止匿名访问。 Interesting thing is I can get data from MVC controllers too having access token recieved through oauth. 有趣的是,我可以从MVC控制器获取数据,也可以通过oauth获取访问令牌。

I understand that oauth middleware sets current user while processing request with token. 我知道oauth中间件在处理请求时使用令牌设置当前用户。 Now I added additional attribute for MVC part to reject users with authentication type != DefaultAuthenticationTypes.ApplicationCookie . 现在我为MVC部件添加了额外的属性来拒绝具有身份验证类型的用户!= DefaultAuthenticationTypes.ApplicationCookie

Now requests with tokens will work only for WebAPI. 现在使用令牌的请求仅适用于WebAPI。 Is this a good approach or am I doing something wrong? 这是一个好方法还是我做错了什么?

Is this a good approach? 这是一个好方法吗?

Not really , its not the authentication mechanism you want to prevent, you are likely to want to restrict access to just your MVC front end, the razor templates. 不是真的 ,它不是你想要阻止的身份验证机制,你可能想要限制只访问你的MVC前端,剃刀模板。 You could use a custom filter similar to how it is explained in this response to ASP.NET MVC preventing users from direct URL except your filter should check that Request.Url.Host is in your list of known endpoints. 您可以使用类似于在ASP.NET MVC响应中解释的自定义过滤器, 防止用户使用直接URL,但过滤器应检查Request.Url.Host是否在您的已知端点列表中。

using System;
using System.Web.Mvc;
using System.Web.Routing;

namespace Customer.Filters
{
    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
    public class PreventFromUrl : ActionFilterAttribute
    {
        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            // MVC requests will originate from the same host as the server
            // external apps may not have a referrer or it will be from a different domain
            // If you have your own non-mvc code, in the same domain, we trust you know what you're doing :)
            if (filterContext.HttpContext.Request.UrlReferrer == null 
                || filterContext.HttpContext.Request.Url.Host != filterContext.HttpContext.Request.UrlReferrer.Host)
            {
                return new HttpStatusCodeResult(HttpStatusCode.Forbidden);
            }
        }
    }
}

If a Filter does not work, consider moving your Web API to a separate project, but be aware that this is really just a security by obscurity measure, it is still possible to use cookie based authentication to obtain access to your MVC endpoints once the caller has authenticated. 如果过滤器不起作用,请考虑将您的Web API移动到一个单独的项目,但要注意这实际上只是一个安全措施的安全性,一旦调用者仍然可以使用基于cookie的身份验证来获取对MVC端点的访问权限已通过身份验证。

Using the authentication type alone does not provide any additional security benefits, you are just saying that each route requires specific way to authenticate, you are not doing anything to deny access itself. 单独使用身份验证类型不会提供任何额外的安全性好处,您只是说每条路由都需要特定的方式进行身份验证,您没有做任何事情来拒绝访问本身。

You are expecting all non-MVC traffic to use OAuth, but because your site supports cookies, external apps could still programmatically and legitimately use cookie based authentication and gain access to your MVC controller endpoints. 您希望所有非MVC流量都使用OAuth,但由于您的站点支持cookie,外部应用程序仍可以编程方式合法地使用基于cookie的身份验证并获得对MVC控制器端点的访问权限。

is it important to deny access to your MVC controllers? 拒绝访问您的MVC控制器是否重要?

Your application logic should always be written with security in mind, your server-side controllers should not rely on the front end to validate and sanitise user inputs, any business rules and validation expressed in the user interface should also be evaluated in the controller logic. 您的应用程序逻辑应始终考虑安全性,服务器端控制器不应依赖前端来验证和清理用户输入,还应在控制器逻辑中评估用户界面中表达的任何业务规则和验证。

Perform and design validation and business rules in the back-end first, in your controllers. 首先在控制器中执行和设计后端的验证和业务规则。
Because front end scripts are executed on the client they are therefor in a much more vulnerable state. 因为前端脚本是在客户端上执行的,所以它们处于更加脆弱的状态。 It is trivial to capture and monitor the traffic that the front end sends back to the client, there for it you can work around client-side validations by manipulating the data before sending it back to the server. 捕获和监视前端发送回客户端的流量是微不足道的,因此您可以通过在将数据发送回服务器之前操纵数据来解决客户端验证问题。

Or worse, evolving client technologies might create scenarios where your client-side scripts and logic do not evaluate the way you originally expected, accidentally allowing un-sanitised or invalid data to flow through. 或者更糟糕的是,不断发展的客户端技术可能会创建一种场景,其中客户端脚本和逻辑不会评估您最初的预期方式,从而意外地允许未经过清理或无效的数据流过。

When the controller performs all business rule validation, as we are conditioned to do in Web API, then in general it should not really matter if the end client is your expected MVC client or something custom written. 当控制器执行所有业务规则验证时,由于我们习惯于在Web API中执行,那么一般来说,如果最终客户端是您期望的MVC客户端或自定义编写的内容,那么这并不重要。 Even if someone wrote an app to automate or impersonate a valid user, If the caller has legitimately authenticated, let them in, because they could otherwise login directly through the MVC site manually or through the API. 即使有人编写了一个应用程序来自动化或冒充有效用户,如果调用者已经过合法的身份验证,请让他们进入,因为他们可以手动或通过API直接通过MVC站点登录。

It is pretty easy in MVC apps to put validation in the user interface level and to skip performing the same checks in the server-side, in this scenario, or when your MVC app exposes more data than you want to allow external clients to access it can become important to deny access to these MVC routes for non-mvc callers. 在MVC应用程序中,很容易将验证放在用户界面级别,并在此方案中跳过在服务器端执行相同的检查,或者当您的MVC应用程序公开的数据超出您希望允许外部客户端访问它的数据时对于非mvc调用者来说,拒绝访问这些MVC路由会很重要。

In general, supporting multiple authentication mechanisms is a good approach for an API because it broadens the options that clients can use to interact with the API. 通常,支持多种身份验证机制对于API来说是一种很好的方法,因为它拓宽了客户端可以用来与API交互的选项。 So supporting multiple types of auth to access the WebAPI routes IS a good approach. 因此支持多种类型的auth来访问WebAPI路由一种很好的方法。

This scenario makes it easy for your front end to access data through both the MVC controllers and the WebAPI. 此方案使您的前端可以轻松通过MVC控制器和WebAPI访问数据。 A common scenario that I encounter is when we use the API to secure access to external files and images. 我遇到的常见情况是我们使用API​​来保护对外部文件和图像的访问。 we can put the URL for the resource endpoint directly into and use the auth cookie that is already in the user's browser to access through the API. 我们可以直接将资源端点的URL放入并使用用户浏览器中已有的auth cookie来通过API访问。

Supporting Mutliple Authentication Mechanisms or Providers will increase the attack surface of your API. 支持多个身份验证机制或提供程序将增加API的攻击面。 This not necessarily a bad thing, but it is something to be aware of and to audit. 这不一定是坏事,但需要注意和审核。

Increased attack surface does not automatically mean that the service is more vulnerable, but it does mean that there are more points of potential failure in your authentication. 增加的攻击面不会自动意味着服务更容易受到攻击,但它确实意味着您的身份验证中存在更多潜在的失败点。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM