...避免無Cookie 302重定向給定現有的Web表單應用程序與具有一個web.config某些路徑
<sessionState cookieless="true" ...
我添加了一個的WebAPI的項目,但它意味着任何未來要求在得到了302響應並在URL中給出「cookie」。
我怎樣才能讓SessionState的cookie的忽略
...避免無Cookie 302重定向給定現有的Web表單應用程序與具有一個web.config某些路徑
<sessionState cookieless="true" ...
我添加了一個的WebAPI的項目,但它意味着任何未來要求在得到了302響應並在URL中給出「cookie」。
我怎樣才能讓SessionState的cookie的忽略
我會回答我的問題,因爲這是非常痛苦的,找到正確的信息和工作發生了什麼事情上有一定的路徑(如/ API)。
我想使用WebApi v2並能夠使用現有的基於webforms會話的應用程序,並且還可以使用其他任何更標準的身份驗證策略來使用它。
下面的代碼是如何將WebApi嵌入WebForms並支持基於會話和基本身份驗證的大部分完整示例。
所以在Global.asax中,我只是叫MyWebApi.Global.Start();
爲什麼我得到重定向的最關鍵的事情是由於代碼恢復會話狀態的的WebAPI。如果您返回SessionControllerHandler
並且沒有會話,則它將執行重定向以獲取cookie,並且在無Cookie模式下將其添加到URL中。這對我正在使用的代理來說是一場災難。但是,通過檢查它是否嘗試使用標準授權機制並返回正常的WebApi路由處理程序,它不會經歷302重定向。然後它會過濾到Authroization函數,該函數確定它是使用標準授權還是基於Session,然後驗證(根據您在應用程序中的操作方式,此部分需要自定義)
public static class Global
{
public static void Start()
{
GlobalConfiguration.Configure(Register);
}
private static void Register(HttpConfiguration config)
{
var httpControllerRouteHandler = typeof(HttpControllerRouteHandler).GetField("_instance",
System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic);
if (httpControllerRouteHandler != null)
{
httpControllerRouteHandler.SetValue(null,
new Lazy<HttpControllerRouteHandler>(() => new SessionHttpControllerRouteHandler(), true));
}
config.Filters.Add(new AuthenticationFilter());
config.Formatters.JsonFormatter.SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/html"));
// Web API routes
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new {id = RouteParameter.Optional}
);
}
}
public class SessionControllerHandler : HttpControllerHandler, IRequiresSessionState
{
public SessionControllerHandler(RouteData routeData)
: base(routeData)
{
}
}
public class SessionHttpControllerRouteHandler : HttpControllerRouteHandler
{
protected override IHttpHandler GetHttpHandler(RequestContext requestContext)
{
if (requestContext.HttpContext.Request.Headers.Get("Authorization") != null)
{
return new HttpControllerHandler(requestContext.RouteData);
}
return new SessionControllerHandler(requestContext.RouteData);
}
}
public class AuthenticationFilter : AuthorizationFilterAttribute
{
public override void OnAuthorization(HttpActionContext actionContext)
{
if (!Authorize(actionContext))
{
actionContext.Response = new HttpResponseMessage(HttpStatusCode.Unauthorized);
return;
}
base.OnAuthorization(actionContext);
}
private static bool Authorize(HttpActionContext actionContext)
{
try
{
var request = actionContext.Request;
var authorization = request.Headers.Authorization;
var roles = new string[0];
if (authorization != null)
{
if (authorization.Scheme == "Basic")
{
var decodedToken = Encoding.UTF8.GetString(Convert.FromBase64String(authorization.Parameter));
var username = decodedToken.Substring(0, decodedToken.IndexOf(":", StringComparison.Ordinal));
var password = decodedToken.Substring(decodedToken.IndexOf(":", StringComparison.Ordinal) + 1);
if(ValidUser(username, password))
{
Thread.CurrentPrincipal =
new GenericPrincipal(new GenericIdentity(username, "Basic"), roles);
if (HttpContext.Current != null)
{
HttpContext.Current.User = Thread.CurrentPrincipal;
}
return true;
}
}
}
var context = request.Properties["MS_HttpContext"] as HttpContextWrapper;
// Use your session...which is up to your implementation
var user = context?.Session["User"]?.ToString();
if (user != null)
{
Thread.CurrentPrincipal = new GenericPrincipal(new GenericIdentity(user, "Session"), roles);
return true;
}
}
catch (Exception)
{
}
return false;
}
}