Доступ к Сервису с проверкой подлинности ServiceStack с помощью Ajax
мы работали с простым примером API, модифицированной версией примера ServiceStack Hello World с аутентификацией. Целью доказательства концепции является создание RESTful API, который содержит сервисы, требующие аутентификации, доступные полностью через Ajax из нескольких различных веб-проектов.
Вы прочитали вики и внедрили Аутентификацию, авторизацию и реализацию CORS (многие результаты [извините, недостаточно доверия, чтобы указать на соответствующую ссылку]). На этом этапе моя служба Hello может аутентифицироваться с использованием специального механизма аутентификации, который переопределяет CredentialsAuthProvider и пользовательский объект сеанса пользователя. Я'мы создали или заимствовали, скорее, простое тестовое приложение (совершенно отдельный проект для имитации наших потребностей) и можем аутентифицироваться, а затем вызывать сервис Hello, передавая имя и получая 'Привет Фред ответ через один сеанс браузера. То есть я могу вызвать путь / auth / credentials в URL, передавая имя пользователя и идентификатор, и получить правильный ответ. Затем я могу обновить URL / hello / fred и получить действительный ответ.
Я не понимаю, как реализовать аутентификацию для всех вызовов AJAX. Мой начальный логин, ниже, работает нормально. Независимо от того, что я делаю, моя попытка вызвать аутентифицированную службу через ajax, я либо получаю ошибку OPTIONS 404, либо ошибку Not Found, либо Origin http // localhost: 12345 (псевдосвязь) не разрешен Access-Control-Allow -Происхождение и т. Д.
Мне нужно идтиэтот маршрут?
Извините, если это сбивает с толку. Я могу предоставить более подробную информацию, если потребуется, но думаю, что этого может быть достаточно, чтобы помочь знающим, чтобы помочь моему непониманию.
function InvokeLogin() {
var Basic = new Object();
Basic.UserName = "MyUser";
Basic.password = "MyPass";
$.ajax({
type: "POST",
contentType: "application/json; charset=utf-8",
dataType: "json",
data: JSON.stringify(Basic),
url: "http://localhost:58795/auth/credentials",
success: function (data, textStatus, jqXHR) {
alert('Authenticated! Now you can run Hello Service.');
},
error: function(xhr, textStatus, errorThrown) {
var data = $.parseJSON(xhr.responseText);
if (data === null)
alert(textStatus + " HttpCode:" + xhr.status);
else
alert("ERROR: " + data.ResponseStatus.Message + (data.ResponseStatus.StackTrace ? " \r\n Stack:" + data.ResponseStatus.StackTrace : ""));
}
});
}
РЕДАКТИРОВАТЬ:
Основываясь на ответах и ссылке, предоставленной Стефаном, яМы внесли пару изменений:
Мой Конфиг (Примечание: яиспользуя пользовательскую аутентификацию и объект сеанса, и все работает правильно.)
public override void Configure(Funq.Container container)
{
Plugins.Add(new AuthFeature(() => new CustomUserSession(),
new IAuthProvider[] {
new CustomCredentialsAuthProvider(),
}));
base.SetConfig(new EndpointHostConfig
{
GlobalResponseHeaders = {
{ "Access-Control-Allow-Origin", "*" },
{ "Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS" },
{ "Access-Control-Allow-Headers", "Content-Type, Authorization" },
},
DefaultContentType = "application/json"
});
Plugins.Add(new CorsFeature());
this.RequestFilters.Add((httpReq, httpRes, requestDto) =>
{
//Handles Request and closes Responses after emitting global HTTP Headers
if (httpReq.HttpMethod == "OPTIONS")
httpRes.EndRequest(); // extension method
});
Routes
.Add("/Hello", "GET, OPTIONS");
container.Register(new MemoryCacheClient());
var userRep = new InMemoryAuthRepository();
container.Register(userRep);
}
Мой простой сервис Hello
[EnableCors]
public class HelloService : IService
{
[Authenticate]
public object GET(Hello request)
{
Looks strange when the name is null so we replace with a generic name.
var name = request.Name ?? "John Doe";
return new HelloResponse { Result = "Hello, " + name };
}
}
После выполнения входящего вызова выше, мой последующий вызов сервис Hello теперь выдает ошибку 401, которая является прогрессом, хотя и не там, где мне нужно. (Jquery.support.cors = true установлен в моем файле сценария.)
function helloService() {
$.ajax({
type: "GET",
contentType: "application/json",
dataType: "json",
url: "http://localhost:58795/hello",
success: function (data, textStatus, jqXHR) {
alert(data.Result);
},
error: function (xhr, textStatus, errorThrown) {
var data = $.parseJSON(xhr.responseText);
if (data === null)
alert(textStatus + " HttpCode:" + xhr.status);
else
alert("ERROR: " + data.ResponseStatus.Message +
(data.ResponseStatus.StackTrace ? " \r\n Stack:" + data.ResponseStatus.StackTrace : ""));
}
});
}
Опять же, это работает в RESTConsole, если я сначала правильно вызываю / auth / credentials, а затем выполняю вызов / hello.
ЗАКЛЮЧИТЕЛЬНОЕ РЕДАКТИРОВАНИЕ Вслед за СтефаномС советами ниже, включая многие другие ссылки, я наконец-то смог заставить это работать. В дополнение к СтефануС кодом я должен был сделать еще одну модификацию:
Plugins.Add(new CorsFeature(allowedHeaders: "Content-Type, Authorization"));
К следующему вызову: Обновление Йонаса Эрикссонаs CustomAuthenticateAttibute code (который, похоже, использует более старую версию ServiceStack, так как пара функций больше не доступна.
СПАСИБО СНОВА СТЕФАН !!