Spring Security 会话中的纯文本密码

Posted

技术标签:

【中文标题】Spring Security 会话中的纯文本密码【英文标题】:Plain text password in Spring Security session 【发布时间】:2017-02-27 02:30:47 【问题描述】:

我正在开发一个使用出色的 Spring Security 插件的 Grails 应用程序。身份验证通过保护应用程序 URL 的 Oracle Access Manager 进行。所以我只使用 PreAuth 过滤器,而不必担心密码。到现在为止。

我们需要集成另一个应用程序(管理冷冻样本并需要用户访问管理,以便用户看不到其他人的样本)并使用 LDAP。该应用程序公开了一个 API,该 API 接受用户名密码并根据该用户的访问权限返回数据(没有代表用户功能)。

问题是我需要向用户询问他们的密码并将纯文本密码发送到该服务。所以散列和编码需要是可逆的,我不能只比较散列码。有关如何以最佳方式管理此问题的任何建议?

我正在考虑使用在服务器上创建的随机盐(并且每 6 小时循环一次),对密码进行编码并将其设置在一个短暂的 cookie 中,并在调用外部服务时在服务器上对其进行解码.这样,潜在的攻击者将需要来自服务器内存的数据和来自用户系统的 cookie,并且我不会在任何地方存储纯文本密码。只是一种天真的尝试。非常愿意接受建议。

【问题讨论】:

“问题是我需要向用户询问他们的密码并将纯文本密码发送到该服务。”。 -- 正是问题所在。如果在某些时候您需要纯文本密码,请解决而不是混淆问题。 @Krease,不确定您是否对演示文稿感到恼火。如果他们不想阅读背景,我使用粗体字符让用户回答我的问题。我不确定你的意思。如果这就是您的意思,我无法解决需要密码的外部 API。需要建议以最好地管理它。我是如何混淆这个问题的? 对造成的混乱表示歉意。这里没有烦恼或理解问题。您正在寻找不更改 API 的解决方案。我认为这是XY problem - 询问您尝试的解决方案而不是您的实际问题。真正的问题是解密为纯文本密码的要求 - 理想情况下,您可以推迟该要求。我认识到这可能是不可能的,这就是为什么我把它作为评论而不是答案。我关于“​​混淆问题”的声明是对 salts/encodings/etc 的响应以隐藏纯文本问题 【参考方案1】:

所以我破解了我的一个应用程序,使其像这样工作:

在用户类中:(Spring Security User.groovy)

static transients = ['springSecurityService', 'rawPassword']

//To bypass facebook users who log in via facebook
//we will back up original hashed password string
//log them in then save old password has by calling user.rawPassword=oldHash
//this will update underlying password with string hash value
void setRawPassword(String p) 
    password=p

然后在相关服务中

//Get old password hash
def oldPassword=user?.password
        String authPassword
        if (oldPassword) 
            def uid = user.password + new UID().toString() + prng.nextLong() + System.currentTimeMillis()
            MessageDigest digest = MessageDigest.getInstance("SHA-256");
            byte[] hash = digest.digest(uid.getBytes("UTF-8"));
            def token1 = hash.encodeBase64()
            user.password = token1
            //Generate a random password
            authPassword = token1
            //Update user Password to be random Password
            UsernamePasswordAuthenticationToken uat1 = new UsernamePasswordAuthenticationToken(user.username, authPassword, null)
            uat1.setDetails(user)
            SecurityContext context = SecurityContextHolder.getContext()
            //Re-setAuthentication of springSecurity using new Password
            context.setAuthentication(uat1)
            if (oldPassword) 
                //Now we are authenticated let's set back the original Hash as the hash we collected in oldPassword 
                //just before doing the hack
                user.rawPassword = oldPassword
                user.save(flush: true)
            
            springSecurityService.reauthenticate user.username
        

这是一个相当丑陋的黑客身份验证作为用户而不更改他们设置的密码(最终)在过程更改并再次更改回来..

我不推荐它,但它可能比您所概述的更容易

【讨论】:

以上是关于Spring Security 会话中的纯文本密码的主要内容,如果未能解决你的问题,请参考以下文章

Spring Security 5中的默认密码编码器

如何避免春季安全中的纯文本LDAP密码?

带有 LDAP 注销的 Spring Security 无法删除会话

如何使用 Spring Security 管理 Spring Boot 中的会话?

具有会话获取在线用户的 Spring Security 返回空

会话中的spring security facebook错误