我一直在研究一个简单的 API 示例,它是带有身份验证的 ServiceStack Hello World 示例的修改版本。概念证明的目标是创建一个 RESTful API,其中包含需要身份验证的服务,这些服务完全可以通过 Ajax 从几个不同的 Web 项目中访问。
我已经阅读了 wiki 并实现了身份验证和授权以及实现 CORS(许多结果 [对不起,没有足够的信任指向相关链接])。此时,我的 Hello 服务可以使用覆盖 CredentialsAuthProvider 和自定义用户会话对象的自定义身份验证机制进行身份验证。我创建或借用了一个简单的测试应用程序(一个完全独立的项目来模拟我们的需求),可以进行身份验证,然后调用 Hello 服务,传递一个名称,并通过一个单一的接收“Hello Fred”响应浏览器会话。也就是说,我可以调用 url 中的 /auth/credentials 路径,传递用户名和 id,并收到正确的响应。然后我可以将 url 更新为 /hello/fred 并接收有效响应。
我的理解失败是如何为所有 ajax 调用实现身份验证。我在下面的初始登录工作正常。无论我做什么,我尝试通过 ajax 调用经过身份验证的服务,我要么收到 OPTIONS 404 错误或 Not Found 错误,要么 Origin http // localhost:12345 (pseudo-link) is not allowed by 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 : ""));
        }
    });
}
编辑:
根据 Stefan 提供的回复和链接,我做了一些更改:
我的配置 (注意:我正在使用自定义身份验证和会话对象,并且一切正常。)
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>("/Hello", "GET, OPTIONS");
    container.Register<ICacheClient>(new MemoryCacheClient());
    var userRep = new InMemoryAuthRepository();
    container.Register<IUserAuthRepository>(userRep);
}
我的简单问候服务
[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 : ""));
        }
    });
}
同样,如果我首先正确调用 /auth/credentials,然后再调用 /hello,这在 RESTConsole 中有效。
最终编辑 在 Stefan 的建议下,包括许多其他链接,我终于能够得到这个工作。除了 Stefan 的代码之外,我还必须进行一项额外的修改:
Plugins.Add(new CorsFeature(allowedHeaders: "Content-Type, Authorization"));
迎接下一个挑战:更新 Jonas Eriksson 的 CustomAuthenticateAttibute 代码(似乎使用的是旧版本的 ServiceStack,因为一些功能不再可用。
再次感谢斯特凡!!