آشنایی با OWIN و بررسی نقش آن در ASP.NET Core
نویسنده: سیروان عفیفی
تاریخ: ۱۳۹۵/۰۶/۳۰ ۱۹:۳۰
آدرس: www.dntips.ir
| مطالب | ۳۶۹۴ |
| نویسندگان | ۲۷۶ |
| گروههای مطالب | ۱۰۲۴ |
| نقشههای راه | ۱۱۹ |
| دورهها | ۱۴ |
| اشتراکها | ۱۷۹۱۴ |
| ضروری؟ | نام کلید | مقدار |
| بله | "owin.RequestBody" | یک Stream همراه با request body. اگر body برای request وجود نداشته باشد، Stream.Null به عنوان placeholder قابل استفاده است. |
| بله | "owin.RequestHeaders" | یک دیکشنری به صورت IDictionary<string, string[]> از هدرهای درخواست. |
| بله | "owin.RequestMethod" | رشتهایی حاوی نوع فعل متد HTTP مربوط به درخواست (مانند GET and POST ) |
| بله | "owin.RequestPath" | path درخواست شده به صورت string |
| بله | "owin.RequestPathBase" | قسمتی از path درخواست به صورت string |
| بله | "owin.RequestProtocol" | نام و نسخهی پروتکل (مانند HTTP/1.0 or HTTP/1.1 ) |
| بله | "owin.RequestQueryString" | رشتهای حاوی query string ؛ بدون علامت ? (مانند foo=bar&baz=quux ) |
| بله | "owin.RequestScheme" | رشتهایی حاوی URL scheme استفاده شده در درخواست (مانند HTTP or HTTPS ) |
| ضروری؟ | نام کلید | مقدار |
| بله | "owin.ResponseBody" | یک Stream جهت نوشتن response body در خروجی |
| بله | "owin.ResponseHeaders" | یک دیکشنری به صورت IDictionary<string, string[]> از هدرهای response |
| خیر | "owin.ResponseStatusCode" | یک عدد صحیح حاوی کد وضعیت HTTP response ؛ حالت پیشفرض 200 است. |
| خیر | "owin.ResponseReasonPhrase" | یک رشته حاوی reason phrase مربوط به status code ؛ اگر خالی باشد در نتیجه سرور بهتر است آن را مقداردهی کند. |
| خیر | "owin.ResponseProtocol" | یک رشته حاوی نام و نسخهی پروتکل (مانند HTTP/1.0 or HTTP/1.1 )؛ اگر خالی باشد؛ “owin.RequestProtocol” به عنوان مقدار پیشفرض در نظر گرفته خواهد شد. |
<package id="Microsoft.Owin" version="3.0.1" targetFramework="net461" /> <package id="Microsoft.Owin.Host.SystemWeb" version="3.0.1" targetFramework="net461" /> <package id="Owin" version="1.0" targetFramework="net461" />
using Owin;
namespace SimpleOwinWebApp
{
public class Startup
{
public void Configuration(IAppBuilder app)
{
}
}
} using Owin;
namespace SimpleOwinWebApp
{
public class Startup
{
public void Configuration(IAppBuilder app)
{
app.Use(async (ctx, next) =>
{
await ctx.Response.WriteAsync("Hello");
});
}
} Func<IOwinContext, Func<Task>, Task> handler
app.Use(async (ctx, next) =>
{
var response = ctx.Environment["owin.ResponseBody"] as Stream;
using (var writer = new StreamWriter(response))
{
await writer.WriteAsync("Hello");
}
});
using System;
using Microsoft.Owin.Hosting;
namespace SimpleOwinConsoleApp
{
class Program
{
static void Main(string[] args)
{
using (WebApp.Start<Startup>("http://localhost:12345"))
{
Console.WriteLine("Listening to port 12345");
Console.WriteLine("Press Enter to end...");
Console.ReadLine();
}
}
}
} using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
namespace SimpleOwinCoreApp
{
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
loggerFactory.AddConsole();
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.Run(async (context) =>
{
await context.Response.WriteAsync("Hello World!");
});
}
}
} using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
namespace SimpleOwinCoreApp.Middlewares
{
public class SimpleMiddleware
{
private readonly RequestDelegate _next;
public SimpleMiddleware(RequestDelegate next)
{
_next = next;
}
public async Task Invoke(HttpContext ctx)
{
// قبل از فراخوانی میانافزار بعدی
await ctx.Response.WriteAsync("Hello DNT!");
await _next(ctx);
// بعد از فراخوانی میانافزار بعدی
}
}
} app.UseMiddleware<SimpleMiddleware>();
"Microsoft.AspNetCore.Owin": "1.0.0"
app.UseOwin(pipeline =>
{
pipeline(next => new MyKatanaBasedMiddleware(next).Invoke)
}); using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
namespace SimpleOwinAspNetCore.Middleware
{
public class IpBlockerMiddleware
{
private readonly RequestDelegate _next;
private readonly IpBlockerOptions _options;
public IpBlockerMiddleware(RequestDelegate next, IpBlockerOptions options)
{
_next = next;
_options = options;
}
public async Task Invoke(HttpContext context)
{
var ipAddress = context.Request.Host.Host;
if (IsBlockedIpAddress(ipAddress))
{
context.Response.StatusCode = 403;
await context.Response.WriteAsync("Forbidden : The server understood the request, but It is refusing to fulfill it.");
return;
}
await _next.Invoke(context);
}
private bool IsBlockedIpAddress(string ipAddress)
{
return _options.Ips.Any(ip => ip == ipAddress);
}
}
} using System.Collections.Generic;
namespace SimpleOwinAspNetCore.Middleware
{
public class IpBlockerOptions
{
public IpBlockerOptions()
{
Ips = new[] { "192.168.1.1" };
}
public IList<string> Ips { get; set; }
}
} using System.Linq;
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.Configuration;
namespace SimpleOwinAspNetCore.Middleware
{
public static class IpBlockerExtensions
{
public static IApplicationBuilder UseIpBlocker(this IApplicationBuilder builder, IConfigurationRoot configuration, IpBlockerOptions options = null)
{
return builder.UseMiddleware<IpBlockerMiddleware>(options ?? new IpBlockerOptions
{
Ips = configuration.GetSection("block_list").GetChildren().Select(p => p.Value).ToArray()
});
}
}
} {
"block_list": [
"192.168.1.1",
"localhost",
"127.0.0.1",
"172.16.132.151"
]
} public IConfigurationRoot Configuration { set; get; }
public Startup(IHostingEnvironment env)
{
var builder = new ConfigurationBuilder()
.SetBasePath(env.ContentRootPath)
.AddJsonFile("blockedIps.json");
Configuration = builder.Build();
} app.UseIpBlocker(Configuration);