如何从 Grails 中的 Spring Security 获取普通密码或解密密码?

Posted

技术标签:

【中文标题】如何从 Grails 中的 Spring Security 获取普通密码或解密密码?【英文标题】:How to get plain password or decrypt password from Spring Security in Grails? 【发布时间】:2015-10-01 16:45:27 【问题描述】:

我在 Grails 应用程序中使用 Spring Security 插件。保存密码时,它在数据库中以加密格式保存。我想给它发送纯密码。如何得到它?

另一个 android 应用程序使用我的 API。通过我的 API,我需要发送特定用户的密码。

【问题讨论】:

您不想发送纯密码(也不可能)。如果您有一个应用程序并且能够发送一个 plian 密码,我会将其标记为安全风险。允许重置密码。 Deinum...感谢您的回复...另一个应用程序使用了我的 API...对于该应用程序,进一步使用需要向该应用程序发送密码... @Visme 听 M. Deinum。只是不要存储纯文本密码,也不要到处发送。如果您需要重置密码,请生成一个新的一次性密码,将其发送给用户并让用户选择他们选择的新密码。这种方式对用户甚至对您来说都更好,因为如果您的用户数据库遭到破坏,攻击者将获得散列和加盐的密码,而不是真正的密码。 【参考方案1】:

如果您从 db 读取密码:当密码保存到数据库时,它们是 hashed 而不是 encrypted 和 the process involved in hashing is not reversible,所以简单的答案是:不,你不能。


您可以在将密码保存到数据库时使用加密(以便在遇到异常情况时可以解密它们)但这不是一个好主意,that is why hashing functions are preferred to encryption algorithm for saving passwords。


但如果您确实需要这样做并且知道如何处理风险,您可以拦截对user.save() 的调用,特别是拦截密码被编码的beforeInsert()beforeUpdate() 方法。

所以您的用户的beforeInsert()beforeUpdate() 方法将如下所示:

beforeInsert()

    ...
    yourApiService.sendPassword(password)
    ...
    password = securityService.encodePassword(password)
    ...




beforeUpdate()

    ...
    if(isDirty('password'))

        yourApiService.sendPassword(password)
        ...
        password = securityService.encodePassword(password)

    
    ...


【讨论】:

【参考方案2】:

如果您将某些 API 暴露给某些外部应用程序,我对您的建议是使用 spring security rest plugin。要开始使用 spring security rest,请查看greach2014 talk。

如果您仍然坚持使用纯文本密码,那么您不是唯一一个要求这样做的人,而是出于不同的意图。存储纯文本密码背后的唯一逻辑是调试 Spring Security 中的登录问题。它不适用于生产应用程序。其他人发布了similar question 来调试登录问题,Burt Beckwith(spring 安全插件的维护者)写了this blog。在这篇博客中,他解释了如何存储纯文本密码。

【讨论】:

以上是关于如何从 Grails 中的 Spring Security 获取普通密码或解密密码?的主要内容,如果未能解决你的问题,请参考以下文章

如何从 Grails 中的 Spring Security 获取普通密码或解密密码?

grails acegi 迁移到 spring-security-core

如何使用 JOSSO 和 Spring Security 从 Grails 应用程序中的 LDAP 获取自定义属性?

如何使 Grails Spring Security 2.0 中的登录/页面成为初始屏幕?

从 grails 应用程序中的自定义 groovy 文件加载 spring bean

如何删除grails中的spring安全令牌?