Web services ServiceStack web服务安全性
大家好,我刚开始使用Servicestack,已经下载了他们非常全面的bootstrapapi示例,我正在使用它,但仍然存在一些问题。问题在于安全性,在尝试访问受保护的服务时,出现了405个错误。使用authenticate服务,我的身份验证似乎是正确的。请帮忙解释一下。代码如下: 服务:Web services ServiceStack web服务安全性,web-services,security,
servicestack,Web Services,Security,
servicestack,大家好,我刚开始使用Servicestack,已经下载了他们非常全面的bootstrapapi示例,我正在使用它,但仍然存在一些问题。问题在于安全性,在尝试访问受保护的服务时,出现了405个错误。使用authenticate服务,我的身份验证似乎是正确的。请帮忙解释一下。代码如下: 服务: 公共类HelloService:ServiceBase { //Get由所有HTTP谓词(Get、POST、PUT、DELETE等)和端点JSON、XMl、JSV等调用 受保护的覆盖对象运行(Hello请
公共类HelloService:ServiceBase
{
//Get由所有HTTP谓词(Get、POST、PUT、DELETE等)和端点JSON、XMl、JSV等调用
受保护的覆盖对象运行(Hello请求)
{
返回新的HelloResponse{Result=“Hello,Olleär enÖLåL”+request.Name};
}
}
[验证()]
公共类AuthHelloService:RestServiceBase
{
公共对象执行(Hello请求)
{
返回新的HelloResponse{Result=“Hello,”+request.Name};
}
}
[所需角色(“测试”)]
公共类RoleHelloService:RestServiceBase
{
公共对象执行(Hello请求)
{
返回新的HelloResponse{Result=“Hello,”+request.Name};
}
}
以下是AppHost:
公共类HelloAppHost:AppHostBase
{
//告诉Service Stack应用程序的名称以及在哪里找到web服务
public HelloAppHost():base(“helloweb服务”,typeof(HelloService.Assembly){}
公共覆盖无效配置(容器)
{
//注册要为此web应用启用的所有身份验证方法。
Plugins.Add(新建AuthFeature(()=>new AuthUserSession(),new IAuthProvider[]{new CustomCredentialsAuthProvider(),//HTML表单发布用户名/密码凭据
}));
Register(newmemorycacheclient(){FlushOnDispose=false});
//注册用户定义的REST-ful URL
路线
.Add(“/hello”)
.Add(“/hello/{Name}”)
.Add(“/AuthHello”)
.添加(“/RoleHello”);
}
}
更新
如果您将:RestServiceBase替换为:ISevice,那么一切都会正常工作。所以现在的问题是为什么。首先查看wiki文档
我将首先浏览ServiceStack中的文档,以便更好地了解ServiceStack的身份验证工作原理。维基上有很多文档,所以如果你不确定什么东西,你应该先参考一下。这是一个社区维基,所以如果你认为它可以帮助其他人,请随意扩展
如果行为不明确,请参考源代码中的实现
如果你不确定某件事是什么,你应该作为主权威,以及它是如何工作的RequiredRole
只是在每个具有该属性的服务之前运行的角色
RequiredRole属性只调用您的会话.HasRole()
方法,如下所示:
因为它只调用您的会话,所以如果您有自定义会话,您可以覆盖session.HasRole()
的实现
注册和实现CustomUserSession
Social BootstrapApi项目确实实现了它自己的功能,但没有覆盖HasRole()
实现,因此它使用基础中的内置实现,该实现看起来很像角色集合,以查看用户在其会话POCO中是否具有指定的角色:
public virtual bool HasRole(string role)
{
return this.Roles != null && this.Roles.Contains(role);
}
由AuthUserRepository填充的会话属性
角色属性(以及用户会话上的大多数其他属性)由您指定的AuthUserRepository填充,例如,如果您正在使用like,则角色属性将保留在中的角色列中。根据AuthUserRepository的不同,您可以使用UserAuth/UserOAuthProvider POCOs将其存储为OrmLite中的RDBMS表或Redis中的文本blob等
使用AssignRoles/UnAssignRoles服务管理角色和权限
因此,对于具有所需角色(以及通过的授权)的用户,应该将此角色添加到其UserAuth db行条目中。ServiceStack包括2个用于管理用户权限和角色的服务:
OnAuthenticated()
事件来实现这一点,该事件只是检查是否在Web.Config中声明了经过身份验证的用户名,如果是,则调用AssignRoles服务,为经过身份验证的用户提供Admin角色:
if (AppHost.Config.AdminUserNames.Contains(session.UserAuthName)
&& !session.HasRole(RoleNames.Admin))
{
var assignRoles = authService.ResolveService<AssignRolesService>();
assignRoles.Execute(new AssignRoles {
UserName = session.UserAuthName,
Roles = { RoleNames.Admin }
});
}
if(AppHost.Config.AdminUserNames.Contains(session.UserAuthName)
&&!session.HasRole(RoleNames.Admin))
{
var assignRoles=authService.ResolveService();
assignRoles.Execute(新的assignRoles{
UserName=session.UserAuthName,
角色={RoleNames.Admin}
});
}
此外,为了便于阅读,我对代码块进行了修饰,并遵循了降价帮助,但似乎没有应用。在每个代码块之前。感谢您的及时详细回复!事实证明,问题实际上在于继承。当我删除:RestServiceBase并对所有服务使用:IService时,一切都按预期工作,包括安全性。有没有什么地方可以让我了解正确的用法,因为这让我绞尽脑汁了一天半。理想情况下,您应该始终使用ServiceBase/RestServiceBase,除非您有理由不想这样做,例如,您希望实现自己的异常处理。ServiceBase有1个用于所有谓词的实现,其中as RestServiceBase允许您为每个谓词指定impl。一些关于这一点的文档:还有一些关于它的介绍——如果你认为它可以保存的话,可以考虑扩展现有的文档。
public class HelloAppHost : AppHostBase
{
//Tell Service Stack the name of your application and where to find your web services
public HelloAppHost() : base("Hello Web Services", typeof(HelloService).Assembly) { }
public override void Configure(Container container)
{
//Register all Authentication methods you want to enable for this web app.
Plugins.Add(new AuthFeature(() => new AuthUserSession(), new IAuthProvider[] {new CustomCredentialsAuthProvider(), //HTML Form post of UserName/Password credentials
}));
container.Register<ICacheClient>(new MemoryCacheClient() { FlushOnDispose = false });
//register user-defined REST-ful urls
Routes
.Add<Hello>("/hello")
.Add<Hello>("/hello/{Name}")
.Add<AuthHello>("/AuthHello")
.Add<RoleHello>("/RoleHello");
}
}
public bool HasAllRoles(IAuthSession session)
{
return this.RequiredRoles
.All(requiredRole => session != null
&& session.HasRole(requiredRole));
}
public virtual bool HasRole(string role)
{
return this.Roles != null && this.Roles.Contains(role);
}
if (AppHost.Config.AdminUserNames.Contains(session.UserAuthName)
&& !session.HasRole(RoleNames.Admin))
{
var assignRoles = authService.ResolveService<AssignRolesService>();
assignRoles.Execute(new AssignRoles {
UserName = session.UserAuthName,
Roles = { RoleNames.Admin }
});
}