我一直在研究一个简单的API示例,即带有身份验证的ServiceStack Hello World示例的修改版本。概念验证的目的是创建一个RESTful
API,该API包含要求身份验证的服务,这些服务完全可以通过Ajax从多个不同的Web项目访问。
我已经阅读了有关Wiki的认证和授权以及实现CORS的实现,(很多,结果[抱歉,没有足够的信誉指向相关链接])。此时,我的Hello服务可以使用自定义身份验证机制进行身份验证,该机制将覆盖CredentialsAuthProvider和自定义用户会话对象。我已经创建或借用了一个简单的测试应用程序(一个完全独立的项目来模拟我们的需求),并且可以进行身份验证,然后调用Hello服务,传递名称,并通过一个单一的接收“
Hello Fred”响应浏览器会话。也就是说,我可以在url中调用/ auth /
credentials路径,传递用户名和ID,并收到适当的响应。然后,我可以将URL更新为/ hello / fred并收到有效的响应。
我的理解上的分解是如何对所有ajax调用实施身份验证。我的初始登录如下所示。无论我做什么,尝试通过ajax调用身份验证的服务,或者收到OPTIONS404错误或Not Found错误,或者Access-Control-Allow不允许Origin http // localhost:12345(伪链接)
-原产地等
抱歉,这令人困惑。如果需要,我可以提供更多详细信息,但认为这可能足以帮助知识渊博的人解决我的不足。
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);
}
我的简单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 : ""));
}
});
}
同样,如果我先正确地调用/ auth / credentials,然后再调用/ hello,则这在RESTConsole中有效。
最终编辑 按照Stefan的建议,在下面(包括许多其他链接),我终于能够开始工作。除了Stefan的代码外,我还必须进行其他修改:
Plugins.Add(new CorsFeature(allowedHeaders: "Content-Type, Authorization"));
应对下一个挑战:更新Jonas
Eriksson的CustomAuthenticateAttibute代码(由于使用了一些功能,因此似乎正在使用旧版本的ServiceStack。
再次感谢斯蒂芬!
此代码对我有效,基于Wiki文档自定义身份验证和授权
代码还基于ServiceStack上具有自定义身份验证的社区资源CORS
BasicAuth
的博客文章中
对于基本身份验证,自定义提供程序
public class myAuthProvider : BasicAuthProvider
{
public myAuthProvider() : base() { }
public override bool TryAuthenticate(IServiceBase authService, string userName, string password)
{
//Add here your custom auth logic (database calls etc)
//Return true if credentials are valid, otherwise false
if (userName == "admin" && password == "test")
return true;
else
return false;
}
public override void OnAuthenticated(IServiceBase authService, IAuthSession session, IOAuthTokens tokens, Dictionary<string, string> authInfo)
{
//Fill the IAuthSession with data which you want to retrieve in the app
// the base AuthUserSession properties e.g
session.FirstName = "It's me";
//...
// derived CustomUserSession properties e.g
if(session is CustomUserSession)
((CustomUserSession) session).MyData = "It's me";
//...
//Important: You need to save the session!
authService.SaveSession(session, SessionExpiry);
}
}
public class CustomUserSession : AuthUserSession
{
public string MyData { get; set; }
}
在AppHost中
using System.Web;
using ServiceStack; // v.3.9.60 httpExtensions methods, before in ServiceStack.WebHost.Endpoints.Extensions;
using ....
AppHost.Configure
public override void Configure(Container container)
{
SetConfig(new ServiceStack.WebHost.Endpoints.EndpointHostConfig
{
DefaultContentType = ContentType.Json
..
// remove GlobalResponseHeaders because CordFeature adds the CORS headers to Config.GlobalResponseHeaders
});
Plugins.Add(new CorsFeature(allowedHeaders: "Content-Type, Authorization")); //Registers global CORS Headers
this.RequestFilters.Add((httpReq, httpRes, requestDto) =>
{
if (httpReq.HttpMethod == "OPTIONS")
httpRes.EndRequestWithNoContent(); // v 3.9.60 httpExtensions method before httpRes.EndServiceStackRequest();
});
//Register all Authentication methods you want to enable for this web app.
Plugins.Add(new AuthFeature(() => new CustomUserSession(), // OR the AuthUserSession
new IAuthProvider[] {
new myAuthProvider(),
}) { HtmlRedirect = null }); // Redirect on fail
Routes.Add<TestRequest>("/TestAPI/{Id}", "POST,GET, OPTIONS");
....
}
服役中
[Authenticate]
public class TestAPI : Service
{
...
}
在JavaScript中
jQuery.support.cors = true;
function make_base_auth(user, password) {
var tok = user + ':' + password;
var hash = btoa(tok);
return "Basic " + hash;
}
先登录
function Authenticate() {
$.ajax({
type: 'Post',
contentType: 'application/json',
url: serverIP + 'Auth',
cache: false,
async: false,
data: {},
dataType: "json",
beforeSend: function (xhr) {
xhr.setRequestHeader("Authorization", make_base_auth(username, password));
},
success: function (response, status, xhr) {
localStorage.sessionId = data.SessionId;
var UserName = response.userName;
},
error: function (xhr, err) {
alert(err);
}
});
}
并要求
function DoTest() {
var TestRequest = new Object();
TestRequest.name = "Harry Potter";
TestRequest.Id = 33;
var username = "admin";
var password = "test";
$.ajax({
type: 'Post',
contentType: 'application/json',
cache: false,
async: false,
url: serverIP + '/TestAPI/'+ TestRequest.Id,
data: JSON.stringify(TestRequest),
dataType: "json",
beforeSend: function (xhr) {
xhr.setRequestHeader("Session-Id", localStorage.sessionId);
},
success: function (response, status, xhr) {
var s= response.message;
},
error: function (xhr, err) {
alert(xhr.statusText);
}
});
}
这些问题在这里
和这里都是有帮助的。
如果我们可以使用cookie和session,那么对于CredentialsAuthProvider
也是这个答案。
我正在使用预装的Visual Studio解决方案开发我的首批OAuth解决方案之一。 不过,同时我也希望我的服务器应用程序拥有“完全访问权限”。他们需要能够获得列表增加多个用户,删除东西等等。 下面是我的问题,我认为这些问题可以很容易地一起回答: 如何管理两个短期令牌(承载令牌?)连同永久令牌(API令牌?) 我在访问级别上有何不同,因此某些方法需要永久令牌? 在同一方法中,我在访问级别上有何不
我使用以下方法注册了身份验证器:
我正在尝试使用ServerEvents设置servicestack。我已经为ServerEventsFeature添加了插件。我正在使用Javascript服务器事件客户端,我尝试了一个简单的示例,在用户经过身份验证后在客户端上执行此操作。 在apphost文件上: 要向我正在呼叫的客户端发送事件,请执行以下操作: 我成功地在客户端上的show通知功能上接收到它。 然而,订阅服务仍然存在。disp
问题内容: 我可以通过接收到请求的xml 但不是 没有JavaScript错误,没有跨域策略问题。可能是语法错误,但是我找不到合适的教程。有什么建议吗? 问题答案: 我认为您需要纯格式:
问题内容: 我正在尝试访问Googles Contacts API,但由于获得授权而失败。从其他(网络)语言开始,我习惯于使用APIConsole和公共API密钥(授权)。 这样,我不能够刷新令牌并不能确定如何使用公共密钥的accessToken ......相反,我尝试了一个服务帐户: 这是我的例外: 谢谢提示! 问题答案: 不调用我的代码就可以很好地工作。但是您只会拥有一个模拟帐户(ser
我已经使用Spring boot zuul和eureka服务配置了我的微服务。现在我需要验证所有路由/REST API调用。我的意思是,对于所有API,客户端发送一个accessToken。在zuul服务上,在路由到特定服务之前,我必须使用accessToken调用一个微服务(auth服务),该auth服务将检查用户是否存在发送的accessToken。如果accessToken有效,则只应进行路