无法访问密码:它在用户中是私有的

Posted

技术标签:

【中文标题】无法访问密码:它在用户中是私有的【英文标题】:Cannot access password: it is private in User 【发布时间】:2021-11-27 06:34:54 【问题描述】:

我想存储和访问数据库中的密码,但是当我通过帮助实体类和 spring security UserDetails 从数据库中访问密码时,它会抛出一个错误,将密码设为私有,当我去存储密码时它会抛出 make password民众。我不知道如何在 Spring Security 中处理此类问题。我为User 实现了UserDetails,它覆盖了一些像getPassword() 这样的函数,它的返回类型是String,所以我将密码作为字符串参数返回。但是当我将 UserEntity 类中的密码字段声明为 public getPassword() 时会出现问题

Accidental override: The following declarations have the same JVM signature (getPassword()Ljava/lang/String;): 

当将密码字段设为私有时,在将数据存储在数据库中时出现另一个错误

\main\kotlin\com\nilmani\mychat\service\UserService.kt: (38, 14): Cannot access 'password': it is private in 'User'

用户.kt

package com.nilmani.mychat.model

import org.jetbrains.annotations.NotNull
import org.springframework.data.annotation.Id
import org.springframework.data.mongodb.core.mapping.Document
import java.time.LocalDate

@Document
open class User(
    @Id
    var id: String? ="",
    var userName: String? ="",
    var password: String? ="",
    var email: String? ="",
    var createdAt: LocalDate? =LocalDate.now(),
    var updatedAt: LocalDate? = LocalDate.now(),
    var active:Boolean=false,
    @NotNull
    var userProfile: Profile?,
    @NotNull
    var role: MutableSet<Role>? = HashSet()
    ) 
    constructor(user: User?):this(
        user?.id, user?.userName, user?.password, user?.email, user?.createdAt,
        user?.updatedAt, user?.active == true, user?.userProfile, user?.role
    )

    constructor() : this(null)

InstaUserDetails.kt

package com.nilmani.mychat.model

import org.springframework.security.core.GrantedAuthority
import org.springframework.security.core.authority.SimpleGrantedAuthority
import org.springframework.security.core.userdetails.UserDetails
import java.util.stream.Collectors

class InstaUserDetails :User(),UserDetails 
    override fun getAuthorities(): MutableCollection<out GrantedAuthority> 
        return role
            ?.stream()
            ?.map  role -> SimpleGrantedAuthority("ROLE_"+role.name) 
            ?.collect(Collectors.toList())!!
    
    override fun getPassword() : String 
        return "password"
    
    override fun getUsername(): String 
        return "username"
    
    override fun isAccountNonExpired(): Boolean 
        return isAccountNonExpired
    
    override fun isAccountNonLocked(): Boolean 
        return isAccountNonLocked
    
    override fun isCredentialsNonExpired(): Boolean 
       return isCredentialsNonExpired
    
    override fun isEnabled(): Boolean 
        return isEnabled
    

用户服务.kt

package com.nilmani.mychat.service

import com.nilmani.mychat.model.Role
import com.nilmani.mychat.model.User
import com.nilmani.mychat.repository.UserRepository
import org.slf4j.Logger
import org.slf4j.LoggerFactory
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.security.authentication.AuthenticationManager
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken
import org.springframework.security.core.Authentication
import org.springframework.security.crypto.password.PasswordEncoder
import org.springframework.stereotype.Service
import java.util.*


@Service
class UserService 
    val log : Logger = LoggerFactory.getLogger(UserService::class.java)
    @Autowired
    private lateinit var userRepository: UserRepository
    @Autowired
    private lateinit var passwordEncoder: PasswordEncoder
    @Autowired
    private lateinit var authenticationManager: AuthenticationManager
    @Autowired
    private lateinit var jwtTokenProvider: JwtTokenProvider

    fun register(user:User, role:Role): User 
        log.info("Register user ", user.userName)
        if (userRepository.existsByUserName(user.userName!!) == true) 
            log.warn("UserName already Exist", user.userName)
        
        if (userRepository.existsByEmail(user.email!!) == true) 
            log.warn("This email already Registred", user.email)
        
        user.active = true
        user.password = passwordEncoder.encode(user.password)
        user.role = user.role
        /**it auto automatically get the user type from role due to some conflict  set role provided by user*/
        return userRepository.save(user)
    

如果公开密码,我会在 InstaUserDetails 类中遇到错误 getPassword()。如果在User 类中将密码字段设为私有,我在保存密码时会在UserService 类中出现错误。如何在单个实体类中处理这个多重问题。我在密码上应用了可变密码和私钥,例如 private var password:String?="" 但在register() 中的密码保存时出现错误,该密码在我的UserService 类中定义。

【问题讨论】:

可能还值得指出的是,出于安全原因,直接存储密码通常是一个非常糟糕的主意;存储密码的 hash 通常更安全。 (这样,您可以验证用户是否输入了正确的密码——但访问您的数据库的恶意行为者不会获得您所有用户的密码。) 对密码进行编码总比没有好,但仍然可以被解码。 【参考方案1】:

您可以将密码参数设为私有,并为其显式创建 getter 和 setter。

open class User(
    private var password: String? = "",
    private var username: String? = "",
    // ...
) 
    constructor() : this(null)

    open fun getPassword(): String? 
        return password
    

    open fun setPassword(password: String?) 
        this.password = password
    

请注意,在InstaUserDetails 中,如果您只想从User 继承getPassword(),则无需覆盖getPassword()

【讨论】:

以上是关于无法访问密码:它在用户中是私有的的主要内容,如果未能解决你的问题,请参考以下文章

电脑没有密码导致的共享目录别人无法访问

使用 gdb 调试多线程代码但无法访问私有变量?

无法从Web应用程序访问Azure公共和私有证书

这实际上是如何完成的?

即使 IAM 策略授予访问权限,Web 应用程序也无法访问私有 s3 文件

Php登录问题(用户无法登录,用户可以使用其他密码访问自己的帐户)