我有一个使用Spring Security的Grails应用程序。
这个应用程序基本上是一个内容管理系统,所以它是一个CRUD。
我的网址访问基本上如下格式:
/$controller/$action/$id
这是遇到问题的地方。这发生在控制器中,例如,为了更改用户,我有以下URL:
/user/update/1
进入控制器我有以下代码:
def update(Long id) {
def user = User.get(id);
[user: user]
}
这就是问题所在。如果用户直接更改(id)而不检查请求中的用户ID是否正确,则任何人都可以浏览我的系统用户。现在我有一个大问题。
我认为解决方案是为每个注册系统创建一个唯一的哈希,这会阻碍用户理解,例如,ID 1具有哈希123aabbCCDD,例如。
但我在系统中有很多寄存器和许多域,我不知道这是否是最好的解决方案。
我需要帮助才能知道,例如,使用弹簧安全性,我可以做这种事情。
我试图找到问题的解决方案,但我不确定要搜索哪些字词,所以如果已经存在类似我的问题,请将链接放在评论中。
感谢。
答案 0 :(得分:2)
正如约书亚所指出的,如果这是一个普遍的问题,你需要限制哪些用户(或哪些角色)可以执行特定的操作,spring-security-acl插件将有所帮助。但这可能很繁琐,因为您通常需要以细粒度的方式对事物进行建模,并且最终在数据库中得到 lot 的ACL数据。
但是,如果您只想限制用户自行编辑,请不要传递用户ID。如果操作需要身份验证,您已经知道用户是谁。如果是这种情况,请将操作更改为
def springSecurityService
def update() {
[user: springSecurityService.currentUser]
}
通常可以避免使用ACL的相关工作流程允许用户编辑他们拥有的内容,例如一个CreditCard
。假设您在static hasMany = [creditCards: CreditCard]
班级User
和static belongsTo = [user: User]
(或User user
)中有def springSecurityService
def update(Long id) {
def user = springSecurityService.currentUser
def card = CreditCard.findByIdAndUser(id, user)
[creditCard: card]
}
,那么您可以允许表单发送信用卡ID,但您只需要使用修改后的查询,例如
select ... from credit_card where id=? and user_id=?
最终的SQL查询看起来像get()
,与select ... from credit_card where id=?
调用where
的SQL相比,它具有很大的安全优势。恶意用户仍然可以尝试发送他们想要的任何ID,但由于char **m_data
子句检查id和用户外键,如果他们没有作为卡所有者登录,则查找器将返回null,您可以将其视为错误或黑客,并且不允许访问。
请注意,您所描述的哈希方法并不是非常安全 - 它只是通过默默无闻的安全措施"。如果每个用户的哈希是不变的,那么找出用户的哈希是什么并且伪造请求并不困难(例如,同事可以只看另一个用户的监视器并看到他们浏览器中的网址。)