Spring MVC、RESTful 服务和Apache Shiro 策略
我正忙于一个项目,该项目需要 REST API 来允许用户访问服务器上的信息。我让系统使用 Spring MVC 和 MappingJacksonJsonView 来在需要时返回 JSON。
我现在希望在系统中包含安全性,首先确保用户进行身份验证并拥有访问资源的正确权限,其次我希望对数据进行足够细粒度的控制,以确保用户只能访问公开可用的资源资源的一部分,或者如果他们具有整个资源的正确权限。
例如:
场景 A:用户 A 希望访问他们的消息列表以及他们的姓名和电话号码。然后他们将获得身份验证,并且他们的权限将允许他们访问自己的所有信息。
场景 B:用户 A 希望访问用户 B 的电话号码 - 因此在响应中排除用户 B 的消息列表,因为 A 无权访问该部分信息。
- Q1:有没有一种简洁的方法 关于使用 Apache Shiro 执行此操作 和Spring MVC?
- Q2:有人吗 有示例或教程链接 关于别人如何取得成就 这?
- Q3:什么样的权限 方案,使用Shiro,将是最 有效地允许这种类型的罚款 粒度控制?
我以前没有使用过 Shiro,但从使用示例和阅读文档来看,这似乎是可能的,而且 Shiro 最适合该解决方案。不过,我对其他解决方案持开放态度。
编辑:一个解决方案,我不知道 Shiro & 是否可以实现这一点。 Jackson 的任务是在我的 POJO 中注释属性,我可以将其标记为公共或私有。或者更好的是,用访问它们所需的权限来标记它们。然后,当 Jackson 打印出对象的 JSON 表示形式时,它可以检查当前属性的权限,并决定是否从其注释中打印该属性。
I am busy working on a project that needs a REST API to allow users to access their information on a server. I have the system working using Spring MVC and the MappingJacksonJsonView
to return JSON where needed.
I now want to include security in the system to firstly, ensure users authenticate themselves and have the correct permissions to access a resource and secondly I want to have enough fine-grained control of the data to make sure that a user can only access publicly available portions of a resource or if they have the correct permissions the entire resource.
So for example:
Scenario A: User A wants to access their list of messages, as well as their name and phone number. They would then get authenticated and their permissions would allow them to access all of their own information.
Scenario B: User A wants to access User B's phone number - therefore excluding User B's list of messages in the response as A doesn't have permissions to access that portion of info.
- Q1: Is there a neat way of going
about doing this using Apache Shiro
and Spring MVC? - Q2: Does anybody
have an example or link to a tutorial
on how somebody else has achieved
this? - Q3: What sort of permissions
scheme, using Shiro, would be most
efficient to allow this type of fine
grained control?
I haven't worked with Shiro before, but from playing with examples and reading the documentation it looks like this is possible and that Shiro would be the best fit for the solution. I am open to other solutions though.
Edit: One solution, and I have no idea if this is possible with Shiro & Jackson, is to annotate properties in my POJO's that I can mark as public or private. Or even better, mark them with the permission necessary to access them. Then when Jackson prints out the JSON representation of the object it can inspect the permissions for the current property and decide whether to print the property or not from its annotation.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
对于这个问题,解决方案非常简单。我为 Jackson 创建了一组视图类:
然后,我通过添加以下内容来注释我想要保护的每个实体的所有 getter 方法:
上述规则的含义是,只有在系统内经过身份验证的用户才能查看用户的电话数字。
或者,
然后我创建了一个接口并在所有安全实体中实现了该接口:
下面是该方法的实现:
现在来看看魔术吧。扩展
MappingJacksonJsonView
并重写以下方法:您还可以重写
setObjectMapper
方法,以在 Spring 设置您的MappingJacksonJsonView
时捕获 objectMapper。我的 Spring 配置如下所示:
那么我们现在有什么?每次需要将响应反序列化为 JSON 时,都会调用 renderMergedOutputModel 方法。如果用户的 ID 在请求中,我们将存储该 ID。然后我们可以循环遍历模型映射并检查每个值是否是 SecurePropertyInterface 以及是否获得其最大权限级别。
这个策略似乎很符合我的目的。当用户请求用户列表时,他们只能获得经过身份验证的属性,但是当用户请求自己的详细信息时,他们只能获得他们的私有属性。
我怀疑这段代码可以进一步改进,但我花了太多时间试图让它不那么复杂。
The solution is pretty simple for this problem. I created a set of view classes for Jackson:
I then annotated all the getter methods for each entity I want to be secured by adding the following:
What the above rule means is that only users who are authenticated within the system my view a user's phone number.
Or
I then created an interface and implemented that interface in all my secure entities:
And here is the implementation of that method:
Now for the magic. Extend
MappingJacksonJsonView
and override the following method:You can also override the
setObjectMapper
method to capture the objectMapper when Spring sets up yourMappingJacksonJsonView
.My Spring config looks like this:
So what do we have here now? Every time a response needs to be deserialized to JSON the renderedMergedOutputModel method is called. If the user's id is in the request we store that. We can then loop through the model map and check if each value is a SecurePropertyInterface and if it is get its max permission level.
This strategy seems to serve my purposes properly. When users request a list of users then they get only the authenticated properties, but when users request their own details they get only their private properties.
I suspect this code can be improved further though, but I have spent way too much time trying to make it less complicated.