فیلتر های امنیت در Web API
سه شنبه 17 آذر 1394در این مقاله راجع به فیلترهایی که برای تامین امنیت Web Api کاربرد دارند و همچنین سایر روش های امنیتی درWeb Api صحبت خواهیم کرد.
کاری که فیلتر های احراز هویت انجام می دهند اعتبارسنجی درخواست های ورودی است . هم web Api و هم mvc از فیلترها احراز هویت پشتیبابی می کنند.این فیلتر ها را می توان برای کنترلر ها و action های موجود در برنامه خود استفاده کنید .یعنی احراز هویت در سطوح مختلف از جمله کنترلر و action قابل پیاده سازی است .
فرآیند احراز هویت در وب چگونه است؟
فر آیند احراز هویت در وب به این صورت است که قبل از اجرا شدن Actionمورد نظر وب یک لیستی از فیلتر های احراز هویتی که برای این actionدر نظر گرفته شده است می سازد.این لیست شامل تمام فیلتر های با محدوده کنترلر اکشن و Global است.
پس از این مرحله وب AuthenticateAsync هر فیلتر را فراخوانی می کند.هر فیلتر می تواند درخواست رسیده را بررسی کرده و از صحت آن مطمئن شود.اگر درخواست درست بود و از فیلتر رد شد فیلتر مورد نظر به انتهای درخواست IPrincipal را اضافه می کندو اگر درخواست درست نباشد یک خطایی نشان داده میشود.
با فرض اینکه خطایی وجود نداشته باشد درخواست بقیه مسیر برای اجرا در سرور و بازگشت پاسخ را ادامه می دهد.
همان طور که می دانید Authentication یعنی چه کاربری به سایت وارد شده است. Authorization ، سطح دسترسی کاربر وارد شده به سیستم و اعمالی را که مجاز است انجام دهد را مشخص میکند.
برای اعمال جنبه های مختلف امنیت در web Api گزینه های مختلفی وجود دارد از جمله :
HTTP Module
میان افزار OWIN
Message Handler
Action Filter
Authorization Filter
Authentication Filter
HTTP Module
پردازش یک صفحه وب مراحل مختلفی دارد و در هر مرحله یک سری رویدادهای خاصی اجرا می شوند.با کمک HTTP Module می توانیم در این رویدادها تغییراتی ایجاد کنیم .یکی از این عملیات می تواند اعتبار سنجی درخواست ها برای تامین امنیت سرویس Web Api باشد.
دو عدد از مهمترین توابع در این قسمت BeginRequest و EndRequest است .برای نوشتن یک HTTP Moduleباید از اینترفیس مربوط به آن ارث بری کرد و بعد تک تک توابع را بازنویسی کرد .به کد زیر توجه کنید
class SampleHttpModule : IHttpModule { public void Dispose(){} public void Init(HttpApplication context) { context.BeginRequest += new EventHandler(context_BeginRequest); context.EndRequest += new EventHandler(context_EndRequest); } void context_BeginRequest(object sender, EventArgs e) { //handle BeginRequest here... } void context_EndRequest(object sender, EventArgs e) { //handle EndRequest here... } }
بعد از تعریف کردن این HTTP Module باید آنرا به web.config معرفی کنیم
<configuration> <system.web> <httpModules> <add name="SampleHttpModule" type="MyApplication.SampleHttpModule"/> </httpModules> </system.web> </configuration>
Owin MiddleWare
Owin یا Open Web Inteface for .NET یک لایه انتزاعی بین وب سرور ما و برنامه به وجود می آورد. ASP.NET Web API 2 کاملا از owin پشتیبانی می کند .می توانید در برنامه خود از signalR هم به همراه web Api استفاده کنید هر دو اینها مشکلی با owin ندارند
در این میان افزار می توانید تعهدات امنیتی برای برنامه خود در نظر بگیرید.
Message Handler
این گزینه توسط web Api ارائه شده است .استفاده از این مورد برای امنیت فواید بسیاری دارد.Message Handler تنها برای درخواست هایی از نوع web Api کاربرد دارد. از Message Handler می توانید به عنوان یک Handler کلی هم استفاده کنید و بعد این handler کلی را برای بررسی امنیت در درخواست ها و کنترلر های خود به کار گیرید.البته این نکته را در نظر داشته باشید که پایین ترین سطح امینت در این گزینه هایی که گفته شد مربوط به Message Handler می باشد.
فیلتر های Action
به صورت پیش فرض همه کنترلر ها و Action ها قابل دسترسی توسط همه کاربران هستند .متدهای public در واقع دسترسی را به همه می دهند و هیچ اعتبارسنجی به صورت پیش فرض انجام نمی دهند.برای اینکه از کنترلر ها و action ها محافظت کنیم از یک صفتی به نام authorize باید استفاده کنیم .
فیلتر دیگری هم در web api اضافه شده است که نام Authentication است .این فیلتر بعد از message handlers و قبل از تمام فیلتر های دیگر اجرا می شود. برای Authentication روش های سنتی و بر مبنای token وجود دارد .در سیستم سنتی کاربر درخواست دیدن صفحه ای را به سرور ارسال می کند بعد از اینکه درخواست به سمت سرور ارسال شد اطلاعات این کاربر در بانک چک می شود اگر این کاربر وجود داشت یک session برای او ایجاد می گردیدو بعد بر اساس سطوح دسترسی یا همان role اجازه دسترسی به صفحه را به کاربر می دهیم .اما در حال حاضر با توجه به اینکه کاربران موبایل و اندروید در حال افزایش هستند استفاده از session جوابگوی احراز هویت نیست .در این حالت از Token استفاده می کنیم .در روش جدید پس از وارد کردن کلمه عبور و نام کاربری ، اگر این کاربر در دیتابیس ما وجود داشت یک توکن ایجاد کرده و در سمت کلاینت ذخیره می کنیم .از توکن در web api بسیار استفاده می شود.
با استفاده از فیلتر Authentication در web api می توانیم از حملات XSRF جلوگیری کنیم .این حملات از اعتماد سایت ها به کاربرانشان سواستفاده کرده و به جای کاربر به انجام عملیاتی می پردازند .کاربر از این عملیات هیچ اطلاعی ندارد.
ساختن فیلتر های Authentication و Authorization به صورت پشت سر هم
کلا ترتیب اجرا فیلتر ها در mvc و web api به این صورت است که فیلتر های از نوع Authentication قبل از همه اجرا می شوند .بعد از آن فیلتر های از نوع Action اجرا می شوند .بعد از فیلتر ها از نوع action فیلترهایی از نوع Result اجرا میشوند یعنی درست قبل از بازگرداندن نتیجه متد این فیلتر ها اجرا می شوند .
در شکل زیر نحوه ای که درخواست کاربر برای دیدن صفحه ای به سرور ارسال می شود و از فیلتر های احراز هویت عبور می کند نشان داده شده است .
ساخت فیلتر Authentication
برای اینکه خودتان فیلتر ایجاد کنید باید یک اینترفیس بسازید که این اینترفیس از Ifilter ارث بری می کند .کد زیر را ببینید
public interface IAuthenticationFilter : IFilter { Task AuthenticateAsync(HttpAuthenticationContext context, CancellationToken cancellationToken); Task ChallengeAsync(HttpAuthenticationChallengeContext context, CancellationToken cancellationToken); }
حال برای انجام احراز هویت یک متد به نام AuthenticateAsync می نویسیم .کد های این تابع در زیر اَورده شده است .
public Task AuthenticateAsync(HttpAuthenticationContext context, CancellationToken cancellationToken) { var req = context.Request; // Get credential from the Authorization header //(if present) and authenticate if (req.Headers.Authorization != null && "somescheme".Equals(req.Headers.Authorization.Scheme, StringComparison.OrdinalIgnoreCase)) { var creds = req.Headers.Authorization.Parameter; if(creds == "opensesame") // Replace with a real check { var claims = new List<Claim>() { new Claim(ClaimTypes.Name, "badri"), new Claim(ClaimTypes.Role, "admin") }; var id = new ClaimsIdentity(claims, "Token"); var principal = new ClaimsPrincipal(new[] { id }); // The request message contains valid credential context.Principal = principal; } else { // The request message contains invalid credential context.ErrorResult = new UnauthorizedResult( new AuthenticationHeaderValue[0], context.Request); } } return Task.FromResult(0); }
شما می توانید از این متد برای پیاده سازی هسته Authentication استفاده کنید . این متد به نوبه خود authentication challenge را اضافه می کند . authentication challenge زمانی که فرآیند Authentication با شکست مواجه شود به پاسخ 401 سرور اضافه می شود.در زیر کدهای مربوط به authentication challenge آورده شده است
public Task ChallengeAsync(HttpAuthenticationChallengeContext context, CancellationToken cancellationToken) { context.Result = new ResultWithChallenge(context.Result); return Task.FromResult(0); } public class ResultWithChallenge : IHttpActionResult { private readonly IHttpActionResult next; public ResultWithChallenge(IHttpActionResult next) { this.next = next; } public async Task<HttpResponseMessage> ExecuteAsync( CancellationToken cancellationToken) { var response = await next.ExecuteAsync(cancellationToken); if (response.StatusCode == HttpStatusCode.Unauthorized) { response.Headers.WwwAuthenticate.Add( new AuthenticationHeaderValue("somescheme", "somechallenge")); } return response; } }
نحوه استفاده از این فیلتر هایی که تعریف کردیم به این صورت است که در بالای هر فیلتر و یا کنترلر دلخواهی این فیلتر ها را قرار می دهیم .
public static class WebApiConfig { public static void Register(HttpConfiguration config) { // Other Web API configuration code goes here config.Filters.Add(new AuthorizeAttribute()); // Global level } } [Authorize(Roles="admin")] // Controller level public class EmployeesController : ApiController { [Authorize(Users="badri")] // Action method level public string Get(int id) { return “Hello World”; } }
فیلتر AllowAnonymous
این فیلتر اجازه دسترسی تمام کاربران حتی آنهایی که احراز هویت نشده اند را ، به action مورد نظر می دهد. زمانی استفاده می شود که کل یک کنترلر را به role خاصی محدود کرده اید و می خواهید در این کنترلر تنها یک action به صورت آزاد باشد و هر کاربری بتواند از آن استفاده کند.نحوه استفاده از این فیلتر به صورت زیر است
public static class WebApiConfig { public static void Register(HttpConfiguration config) { // Other Web API configuration code goes here config.Filters.Add(new AuthorizeAttribute()); // Global level } } [AllowAnonymous] public class PublicResourcesController : ApiController { public string Get(int id) { return “Hello World”; } }
برای اینکه تنها کاربرانی که از سیستم احراز هویت Token (برای آشنایی با مبحث token به مقاله محافظت برنامه های MVC از حملات CSRF با استفاده از Antiforgery token مراجعه کنید )استفاده می کنند بتوانند به action دسترسی داشته باشند باید ابتدا تمام فیلتر های احراز هویتی که داریم را غیر فعال کنیم و بعد از فیلتر TokenAuthenticator برای احراز هویت کاربران Token استفاده می کنیم .به کد زیر توجه کنید
public class EmployeesController : ApiController { [OverrideAuthentication] // Removes all authentication filters [TokenAuthenticator] // Puts back only the token authenticator public string GetAllowedForTokenOnly(int id) { return “Hello World”; } }
- ASP.net
- 4k بازدید
- 6 تشکر