리디렉션 (302) 예측할 수없는 내가 다른 서버에서 웹 API 메서드를 호출 HttpClient를 사용하는 WPF 응용 프로그램을 가지고있다. 그러나 모든 경우에 문제가 발생합니다. 특히 클라이언트 응용 프로그램이 잠자기에서 깨어날 때 (서버가 일시 중지 된 경우), OK : 200 대신 Found : 302가 반환됩니다.는 HttpClient를 & WebAPI
웹 API 메소드는 실제로 무엇이든 할 수 있으며 사용자가 인증되었는지 확인하기 위해 단지 [Authorize]
속성이 있습니다. 사용자가 인증되지 않은 경우 일반적으로, 그것은 내가 ASP.NET 명시 적으로 폼 인증을 사용하지 않는,하지만 리디렉션 클라이언트가 존재하지 않는, login.aspx을 보내고, BTW (404) 을 반환합니다. 여기
[HttpGet]
public HttpStatusCodeResult IsAuthenticated()
{
return new HttpStatusCodeResult(System.Net.HttpStatusCode.OK);
}
WPF 응용 프로그램 클라이언트 코드 (.NET 4.0) :
public async Task<bool> IsAuthenticated()
{
try
{
Uri address = new Uri(AuthUrl);
var cookieJar = ReadCookiesFromDisk(COOKIE_FILE);
if (cookieJar.Count == 0)
return false;
var handler = new HttpClientHandler
{
CookieContainer = cookieJar,
UseCookies = true,
UseDefaultCredentials = false,
AllowAutoRedirect = false
};
var client = new HttpClient(handler)
{
BaseAddress = address
};
int timeout = 15000;
var task = client.GetAsync(address.ToString());
Task[] tasks = new Task[1];
tasks[0] = task;
if (Task.WaitAny(tasks, timeout) != -1)
{
// task completed within timeout
// checking for redirect, but this should not happen!!!
HttpResponseMessage response = task.Result;
if (response.StatusCode == HttpStatusCode.OK || response.StatusCode == HttpStatusCode.Redirect)
return true;
else
return false;
}
else
{
// timeout logic
return false;
}
}
catch (Exception e)
{
EventLogger.Log(e);
return false;
}
}
클라이언트 인증 코드 :
public async Task<string> Login(string data)
{
try
{
Uri address = new Uri(LoginUrl);
HttpContent content = new StringContent(data, Encoding.UTF8);
content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/json");
var cookieJar = ReadCookiesFromDisk(COOKIE_FILE);
var handler = new HttpClientHandler
{
CookieContainer = cookieJar,
UseCookies = true,
UseDefaultCredentials = false,
AllowAutoRedirect = false
};
var client = new HttpClient(handler)
{
BaseAddress = address
};
HttpResponseMessage response = await client.PostAsync(address.ToString(), content);
response.EnsureSuccessStatusCode();
string body = await response.Content.ReadAsStringAsync();
Uri uri = new Uri(UrlBase);
var responseCookies = cookieJar.GetCookies(uri);
if (responseCookies[".ASPXAUTH"] != null)
WriteCookiesToDisk(COOKIE_FILE, cookieJar);
return body;
}
catch (Exception e)
{
return e.ToString();
}
}
서버 :
비동기를 사용할 때 문 위의HttpResponseMessage response = await client.PostAsync(address.ToString(), content).ConfigureAwait(false);
에 코드
HttpResponseMessage response = await client.PostAsync(address.ToString(), content);
다음3210
public JsonResult LogOn(string userInfo)
{
JavaScriptSerializer serializer = new JavaScriptSerializer();
LogOnModel model = serializer.Deserialize<LogOnModel>(userInfo);
JsonMessage error = null;
if (ModelState.IsValid)
{
try
{
if (WebSecurity.Login(model.UserName, model.Password, persistCookie: model.RememberMe))
{
if (WebSecurity.IsConfirmed(model.UserName))
{
if (model.RememberMe)
Response.Cookies[0].Expires = DateTime.Now.AddDays(30);
else
Response.Cookies[0].Expires = DateTime.Now.AddDays(7);
var person = Dc.People.FirstOrDefault(x => x.UserName == model.UserName);
string fullName = string.Empty;
string email = string.Empty;
if (person != null)
{
fullName = string.Format("{0} {1}", person.FirstName, person.LastName);
email = person.Email;
//fill the session to create the session cookie
Session["1"] = 1;
}
var message = new { FailCount = 0, Message = WebSecurity.GetUserId(model.UserName).ToString(), Success = true, SuccessCount = 0, RedirectUrl = "#/conversations/priority", Name = fullName, UserEmail = email, UserHandle = model.UserName, UserAvatar = person.Avatar };
return Json(message);
}
else
{
error = new JsonMessage { FailCount = 0, Message = "Your aren't authorised to login", Success = false, SuccessCount = 0 };
TempData["Error"] = "Your are not authorised to login";
return Json(error);
}
}
else
{
TempData["Error"] = "The user name or password provided is incorrect.";
error = new JsonMessage { FailCount = 0, Message = "The user name or password provided is incorrect.", Success = false, SuccessCount = 0 };
return Json(error);
}
}
catch (Exception ex)
{
TempData["Error"] = ex.Message;
error = new JsonMessage { FailCount = 0, Message = ex.Message, Success = false, SuccessCount = 0 };
}
}
return Json(error);
}
어떻게 WPF 응용 프로그램은 일반적으로 서버에서 인증합니까? 컴퓨터가 절전 모드에있는 동안 인증 쿠키가 만료되어 웹 API가 클라이언트에 다시 인증하도록 지시 할 가능성이 있습니다 (리디렉션을 사용하는 양식 인증 방식에서). 위의 샘플에서 상태 코드를 확인할 때 302가 성공적으로 인증 된 것으로 간주되는 이유는 무엇입니까? 당신은 302를 얻는다면 웹 API에서 정상적으로 인증 할 수 있습니까? 다음 링크는 웹 API의 인증에 대한 몇 가지 샘플을 제공합니다 (http://www.asp.net/web-api/overview/security). – Markus
302가 성공하면 임시 수정 사항이지만 루트 문제는 해결되지 않습니다. 즉, 서버에서 반환 된 쿠키의 유효 기간은 30 일이지만 302는 훨씬 빨라집니다 (당일). –
클라이언트와 서버 모두에서 인증하는 데 사용할 코드를 표시 할 수 있습니까? – Markus