我一直在通過一個簡單的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