servicestack,Authentication,servicestack" /> servicestack,Authentication,servicestack" />

Authentication 将RequestFilter数据添加到上下文(请求范围),在服务中检索

Authentication 将RequestFilter数据添加到上下文(请求范围),在服务中检索,authentication,servicestack,Authentication,servicestack,我为我的服务实现了基本身份验证。由于ServiceStack的AuthFeature与会话概念紧密结合,因此我实现了一个定制的RequestFilter,它执行无状态基本身份验证(每个请求都有凭证)。我们的auth策略在内部考虑角色和权限 除了身份验证,我们还需要强制执行授权(例如,用户正在操作他拥有的产品)。对于所有服务验证,我们都使用FluentValidation 授权验证包括使用请求参数交叉检查身份验证数据。问题是,我应该将BasicAuthRequestFilter中生成的身份验证数据

我为我的服务实现了基本身份验证。由于ServiceStack的
AuthFeature
与会话概念紧密结合,因此我实现了一个定制的
RequestFilter
,它执行无状态基本身份验证(每个请求都有凭证)。我们的auth策略在内部考虑角色和权限

除了身份验证,我们还需要强制执行授权(例如,用户正在操作他拥有的产品)。对于所有服务验证,我们都使用FluentValidation

授权验证包括使用请求参数交叉检查身份验证数据。问题是,我应该将
BasicAuthRequestFilter
中生成的身份验证数据放在哪里?我是否应该在缓存中对其进行键值配对,例如将
RequestContext
(或唯一标识请求范围的任何其他对象)与
身份验证
对象相关联

我可以在请求Dto中插入
AuthData
,它可以直接在
RequestFilter
中获得,但是这会打乱我们的服务契约设计。我们在单独的DLL中定义DTO,其中只定义服务输入/输出细节

有什么建议吗?
提前感谢。

我也使用自己的自定义身份验证机制,并使自定义角色信息可用于我的服务。我通过在自定义数据库中验证请求来实现这一点,然后自定义数据库可以将信息直接传递给我的自定义
服务
库。这最终意味着访问有关用户权限的信息非常容易

创建自定义的
ServiceRunner

公共类ServiceRunner:ServiceStack.ServiceHost.ServiceRunner
{
PublicServiceRunner(IAppHost、appHost、ActionContext、ActionContext):基本(appHost、ActionContext)
{
}
公共重写对象执行(IRequestContext请求上下文、对象实例、T请求)
{
//检查实例是否为AuthenticatedBase类型
var authenticatedBase=实例作为authenticatedBase;
//如果请求未使用AuthenticatedBase,则允许其正常运行。
if(authenticatedBase==null)
return base.Execute(requestContext、instance、request);
/* 
*需要身份验证。是否在此处检查授权。
*即。
*var authorization=requestContext.GetHeader(“授权”);
*bool=…某些条件;
*/
/*您可以访问您的服务库,因此如果您插入了Db连接
*在使用IoC的应用程序配置中,您可以在此处访问数据库。
*即。
*authenticatedBase.Db
*/
/*
*没有授权?
*抛出新的UnauthorizedException();
*/
/*
*如获授权:
*然后简单设置有关其权限的详细信息
*/
authenticatedBase.AuthData=newauthdata{Id=123,Roles=[],Username=”“};
//传回已验证的基
return base.Execute(requestContext、authenticatedBase、request);
}
}
通过将其添加到您的
AppHost
,配置您的应用程序以使用它:

公共覆盖IServiceRunner CreateServiceRunner(ActionContext ActionContext)
{
返回新的ServiceRunner(此,actionContext);
}
创建自定义类以保存身份验证数据,即用户会话信息,例如:

公共类AuthData
{
公共int Id{get;set;}
公共字符串用户名{get;set;}
公共int[]角色{get;set;}
...
}
然后创建一个自定义服务库

公共类AuthenticatedBase:服务
{
公共AuthData AuthData{get;set;}
}
然后在服务中使用AuthData只是扩展
AuthenticatedBase
的一个例子

公共类CustomerHandler:AuthenticatedBase
{
公共对象获取(ListCustomers请求)
{
//现在可以在处理程序中访问AuthData
var roles=AuthData.Role;//检查他们是否具有列出客户所需的角色
...
}
}
您可能想知道,为什么要在
RequestFilter
上使用
ServiceRunner
而不是
RequestFilter
那么麻烦,但它的主要优点是它提供了对服务库实例的直接访问,而RequestFilter无法使用该实例

RequestFilter
s是在实例化服务库之前运行的,因此您不能从那里填充它

通过访问ServiceBase,我们可以填充值(在本例中为
AuthData
),并可以访问注入的依赖项,如数据库连接

我希望你觉得这有用。您应该能够将大部分现有RequestFilter复制到服务运行程序中。如果你需要更多的帮助,请告诉我


更新以支持属性: 由于无法避免使用attribute方法来处理身份验证需求,因此仍然可以使用此方法:

  • 继续像以前那样进行身份验证和访问筛选
  • 在现有的身份验证机制中,使用
    req.Items.Add
    设置
    AuthData
    ,即
    req
    是您的请求对象

    req.Items.Add(“AuthData”,新的AuthData{Username=”“,Roles=[]…});
    
  • 然后访问服务库中的
    AuthData
    项目:

    公共类AuthenticatedBase:服务
    {
    公共AuthData AuthData
    { 
    获取{return base.Request.Items[“AuthData”]作为AuthData;}
    }
    }    
    

我也使用自己的自定义身份验证机制,使自定义角色信息可用于我的服务。我通过在一个定制的
服务中验证请求来实现这一点,然后可以将信息直接传递给我的定制
服务<