我一直在通过一个简单的API示例,ServiceStack Hello World示例的带有认证的修改版本。概念证明的目标是创建一个RESTful API,其中包含需要完全通过来自多个不同Web项目的Ajax访问身份验证的服务。使用Ajax访问ServiceStack认证服务
我已经阅读了wiki,并且实现了认证和授权,并实现了CORS(许多结果[抱歉,没有足够的信誉指向相关链接])。此时,我的Hello服务可以使用自定义身份验证机制进行身份验证,该身份验证机制覆盖CredentialsAuthProvider和自定义用户会话对象。我创建或借用了一个简单的测试应用程序(一个完全独立的项目来模拟我们的需求),并且可以进行身份验证,然后调用Hello服务,传递一个名称,并通过一个单一接收“Hello Fred”响应浏览器会话。也就是说,我可以调用url中的/ auth/credentials路径,传递用户名和id,并接收适当的响应。然后,我可以将URL更新为/ hello/fred并接收有效的响应。
我理解的细节是如何实现所有ajax调用的身份验证。我在下面的初始登录,工作正常。无论我做什么,尝试通过ajax调用已验证的服务,我都会收到一个OPTIONS 404错误或Not Found错误,或者Access http // localhost:12345(伪链接),Access-Control-Allow -Origin等
我需要去this route吗?
对不起,如果这是混乱。如果需要,我可以提供更多细节,但认为这可能足以帮助知识型人员帮助我理解。
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>("/Hello", "GET, OPTIONS");
container.Register<ICacheClient>(new MemoryCacheClient());
var userRep = new InMemoryAuthRepository();
container.Register<IUserAuthRepository>(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 /中正确的凭据,然后遵循了一个打电话给/你好。
FINAL EDIT 以下Stefan的建议,包括许多其他的链接,我终于能够得到这个工作。除了Stefan的代码,我不得不做出一个额外的修饰:
Plugins.Add(new CorsFeature(allowedHeaders: "Content-Type, Authorization"));
下一个挑战:更新乔纳斯埃里克森的CustomAuthenticateAttibute代码(这显然是利用ServiceStack旧版本的一对夫妇的功能都没有可用时间更长
再次感谢STEFAN!
我很困惑。你能更清楚地陈述你的问题吗? – zanbri
如果没有身份验证,你可以在AJAX中做一个简单的调用来检查CORS是否像这样[answer](http://stackoverflow.com/questions/18923930/sending-data-to-servicestack-restful-service-getting -access-is-denied/18927067#18927067)?你可以在AppHost中检查你的代码吗?在JavaScript中,你写了jQuery.support.cors = true; – stefan2410
感谢斯蒂芬的洞察力。听起来这个人的问题与我所经历的非常相似。我将通过这个例子,看看我的结果是什么,并更新这篇文章。再次感谢。 – ithank