Я знаю, что REST является апатридом, но это требование по дизайну. Нам нужно аутентифицировать запросы API из его родительского приложения, которое является традиционным приложением ASp.net Web Form.Обмен сеансом между веб-приложением Asp.net и веб-интерфейсом Asp.net Web2 (Asp.net Web API2 размещен под веб-приложением Asp.net, доступным для одной конфигурации)
У меня есть совместная сессия в соответствии с этими URL-адресами. http://weblogs.asp.net/lichen/sharing-session-state-over-multiple-asp-net-applications-with-asp-net-state-server
How to maintain the same session id across multiple web applications in ASP.NET
http://www.codeproject.com/Articles/27090/Sharing-Session-Across-Applications
Global.asax код из обоих приложения для обмена сессии
public override void Init()
{
base.Init();
try
{
// Get the app name from config file...
string appName = ConfigurationManager.AppSettings["ApplicationName"];
Logger.LogEx(string.Format("{0} - {1}", appName, appName));
// regenerateId();
if (!string.IsNullOrEmpty(appName))
{
foreach (string moduleName in this.Modules)
{
IHttpModule module = this.Modules[moduleName];
SessionStateModule ssm = module as SessionStateModule;
Logger.LogEx(string.Format("module {0} - ssm {1}", module, ssm));
if (ssm != null)
{
FieldInfo storeInfo = typeof(SessionStateModule).GetField("_store", BindingFlags.Instance | BindingFlags.NonPublic);
SessionStateStoreProviderBase store = (SessionStateStoreProviderBase)storeInfo.GetValue(ssm);
if (store == null) //In IIS7 Integrated mode, module.Init() is called later
{
FieldInfo runtimeInfo = typeof(HttpRuntime).GetField("_theRuntime", BindingFlags.Static | BindingFlags.NonPublic);
HttpRuntime theRuntime = (HttpRuntime)runtimeInfo.GetValue(null);
FieldInfo appNameInfo = typeof(HttpRuntime).GetField("_appDomainAppId", BindingFlags.Instance | BindingFlags.NonPublic);
Logger.LogEx(string.Format("theRuntime {0} - appName {1}", theRuntime, appName));
appNameInfo.SetValue(theRuntime, appName);
}
else
{
Type storeType = store.GetType();
if (storeType.Name.Equals("OutOfProcSessionStateStore"))
{
FieldInfo uribaseInfo = storeType.GetField("s_uribase", BindingFlags.Static | BindingFlags.NonPublic);
uribaseInfo.SetValue(storeType, appName);
}
}
}
}
}
}
catch (Exception ex)
{
}
}
Я состояние сервера включен в web.cofing
sessionState mode="StateServer" stateConnectionString="tcpip=127.0.0.1:122233" cookieless="false" timeout="240" stateNetworkTimeout="3600" />
Код, который я пытаюсь выбрать для сеанса, сохраненного/разделяемого из родительского приложения в приложении child (Web Api2).
protected void Application_AcquireRequestState(object sender, EventArgs e)
{
try
{
string loginMethod = "";
string sFileName = "";
string userName = "";
//string sFileExt = Strings.LCase("" + System.IO.Path.GetExtension(sender.request.filepath.ToString()));
//string serverName = HttpUtility.UrlEncode(Request.ServerVariables("SERVER_NAME"));
//ILog log1 = log4net.LogManager.GetLogger(HttpContext.Current.CurrentHandler.GetType());
if ((HttpContext.Current.Session == null || HttpContext.Current.Session["UserID"] == null) && ConfigurationManager.AppSettings["SSOEnabled"] == "1")
{
Logger.LogEx("Session is null");
userName = "" + GetDomainUserName(HttpContext.Current.User.Identity);
string domainName = "" + GetDomainName(HttpContext.Current.User.Identity);
loginMethod = "Windows Authentication";
if (!string.IsNullOrEmpty(userName))
{
Logger.LogEx("Windows userName extracted");
Logger.LogEx(userName);
Logger.Log(String.Format("Connecting to API with windows username {0}", userName));
}
else if ((HttpContext.Current.Session == null || HttpContext.Current.Session["UserID"] == null))
{
Logger.LogEx("Session is null or UserId not found, exception is thrown");
throw new HttpResponseException(System.Net.HttpStatusCode.Unauthorized);
}
else if ((HttpContext.Current.Session != null && HttpContext.Current.Session["UserID"] != null))
{
loginMethod = "User is logged in via application Login interface";
Logger.LogEx("userName is extracted from Shared Session");
userName = HttpContext.Current.Session["UserName"].ToString();
}
if (userName != null && userName != "")
{
Logger.LogEx(loginMethod);
}
else
{
Logger.LogEx("User Name is blank");
Logger.Log("User should be logged in using Application Login Interface");
throw new Exception("Unauthorized: User should be logged in using Application Login interface");
}
Logger.Log(String.Format("Start request for {0}", HttpContext.Current.Request.Url.ToString()));
}
catch (Exception ex)
{
Logger.Log(ex);
throw;
}
}
При аутентификации устанавливается в Windows, а затем «HttpContext.Current.User» доступен, и мы позволяем API, чтобы получить доступ.
Такая же компоновка должна работать, когда установлена анонимная проверка подлинности, этот случай «HttpContext.Current.Session» должен содержать значения сеанса, установленные родителем, но сам сеанс Null.
Когда мы включаем сеанс в API, сеанс не имеет значения null, но значения из родительского приложения недоступны.
protected void Application_PostAuthorizeRequest()
{
System.Web.HttpContext.Current.SetSessionStateBehavior(System.Web.SessionState.SessionStateBehavior.Required);
}
Моя цель для доступа к переменным сеанса, установленные «Родитель Веб-сайт», чтобы «ребенок Web Api 2 App», пожалуйста, помогите.