【问题标题】:Authentication and RequireRole with ServiceStack使用 ServiceStack 进行身份验证和 RequireRole
【发布时间】:2013-02-13 00:33:35
【问题描述】:

我正在尝试使用 ServiceStack 创建一个简单的 Web 服务。在服务器(服务)端,我首先创建了一个用户“管理员”并为其分配了“管理员”角色。我正在使用 ServiceStack 内置的凭据身份验证,并且它很好地进行了身份验证。但是,对任何使用 [Authenticate] 属性修饰的 Web 服务的任何后续调用都会返回以下错误:

没有为 OAuth 提供者“基本”添加配置

仅供参考:数据库是 RavenDb - 使用 ServiceStack.Authentication.RavenDb。我还在 App_Start.AppHost.Configure() 中注册了一个 MemoryCacheClient。如果您需要查看 App_Start.AppHost 类中的所有代码,请告诉我。

服务器代码(摘录):

namespace MyTest 
{
    [Route("/hello")]
    [Route("/hello/{Name}")]
    [Authenticate]
    public class Hello
    {
        public string Name { get; set; }
    }

    public class HelloResponse
    {
        public string Result { get; set; }
    }

    public class HelloService : Service
    {
        public IUserAuthRepository UserAuthRepo { get; set; }

        public object Any(Hello request)
        {
            return new HelloResponse { Result = "Hello, " + request.Name };
        }
    }
}

客户端:

var client = new JsonServiceClient("http://127.0.0.1:65385/auth/credentials?format=json");
var auth   = new Auth { UserName = "administrator", Password = "12345" };

var authResponse = client.Post(auth);

if (authResponse.ResponseStatus.ErrorCode == null)
{
    client = new JsonServiceClient("http://127.0.0.1:65385/hello");
    client.UserName = "administrator";
    client.Password = "12345";

    // When sending the request - it returns "Not Found"
    var helloResponse = client.Send(new Hello { Name = "John" });
}

编辑:
我的服务的 web.config 看起来与the Hello World tutorial 的第 2a 部分中所写的完全一样

这是我的 AppHost 的配置:

public override void Configure(Funq.Container container)
{
    container.Register(new MemoryCacheClient { FlushOnDispose = false });
    container.Register(new EmbeddableDocumentStore { DataDirectory = "Data" }.Initialize());

    ConfigureAuth(container);
}

private void ConfigureAuth(Funq.Container container)
{
    var appSettings = new AppSettings();

    Plugins.Add(new AuthFeature(() => new CustomUserSession(),
        new IAuthProvider[] {
            new CredentialsAuthProvider(appSettings)}));

    Plugins.Add(new RegistrationFeature());

    container.Register(
        new RavenUserAuthRepository(c.Resolve()));
}

【问题讨论】:

    标签: c# c#-4.0 asp.net-mvc-4 servicestack


    【解决方案1】:

    首先,您应该查看ServiceStack's AuthTests 中一些使用ServiceStack's C# Service Clients 测试身份验证的示例。

    您在 C# ServiceStack 客户端中传递了错误的 url,即您应该只传递托管 ServiceStack 的 Base URI,例如:

    var client = new JsonServiceClient(
        "http://127.0.0.1:65385/auth/credentials?format=json");
    var client = new JsonServiceClient("http://127.0.0.1:65385/hello");
    

    应该只是:

    var client = new JsonServiceClient("http://127.0.0.1:65385/");
    var client = new JsonServiceClient("http://127.0.0.1:65385/");
    

    在使用像 JsonServiceClient 这样的 ServiceStack C# ServiceClient 时,您也不应该输入 ?format=json,因为格式已经隐含在客户端中,它确保通过发送 Accept: application/json HTTP 标头返回 JSON应每一个要求。

    【讨论】:

    • 感谢您的帖子。但是,您编写的任何提示都没有帮助。正如我所写,第一次调用(到 /auth/credentials)工作正常,这意味着显然只使用基本 URI 或我编写的 URL 之间没有区别。查询字符串中的格式参数相同。我已经彻底研究了这些例子,相信我。看看错误信息,我想我缺少一些提供程序配置,但我不知道是什么或如何...
    • 查看 HTTP 流量,您会发现差异 - 您将不必要地重复发布变量。您的 AppHost 配置很可能有问题,但您还没有发布 - 所以没有人能说出来。
    • 我已经编辑了我的原始帖子并添加了我的 AppHost 的一些配置。我现在挖得更深了,发现 [Authenticate] 属性正在寻找基本身份验证,而我使用凭据身份验证...我还看到我的请求中缺少 Authentication 标头...
    • 嘿@mythz 服务堆栈示例中的 AadAuthProvider 类在默认情况下如何没有从 AAD 转换的角色?
    • @ShP 如有任何关于 AadAuthProvider 的问题,请通过ServiceStack.Authentication.Aad project 提出
    【解决方案2】:

    好的,找出问题所在:[Authenticate]、[RequiredRole] 和 [RequiredPermission] 属性适用于基本身份验证(身份验证也适用于摘要身份验证)。因此,如果您想使用这些属性中的任何一个,您必须确保在将 AuthFeature 设置为插件时已将 BasicAuthProvider 添加到 IAuthProviders 列表中。所以,

    Plugins.Add(new AuthFeature(() => new CustomUserSession(),
        new IAuthProvider[] {
            new CredentialsAuthProvider(appSettings)}));

    必须

    Plugins.Add(new AuthFeature(() => new AuthUserSession(),
        new IAuthProvider[] {
            new CredentialsAuthProvider(appSettings),
            new BasicAuthProvider() 
        }));

    我仍然必须在每次通话时以明文形式发送用户名和密码...

    【讨论】:

    • 如果你需要一些加密,BasicAuthProvider 可以在 HTTPS 之上使用。
    【解决方案3】:

    确保您在 ServiceStack 应用程序中注册了 ICacheClient,这样您就不必在每次请求时都发送用户名和密码。您的客户端应该能够不费吹灰之力地处理存储 cookie。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-11-22
      • 1970-01-01
      • 1970-01-01
      • 2017-08-18
      • 1970-01-01
      • 2011-10-17
      相关资源
      最近更新 更多