Spring Boot 2.1.0使用Kotlin数据类更改安全性?

时间:2018-11-08 18:39:20

标签: spring-boot spring-security kotlin

这个问题使我身体不适。

开个玩笑,我一直在尝试使用带有安全性插件的spring-boot向我的Web应用程序添加身份验证层。这是我的数据类。

@Document(collection = "user")
data class User (
        var name : String,
        var password : String,
        var email : String,
        var type : String,
        var status : String,
        var balance : Int
){
    @Id val id : String = ObjectId.get().toHexString()
}

在进行Ctr + C,Ctr + V搜索之后,我成功设置了一些自定义身份验证,该身份验证将从数据库中获取用户信息,如下所示:

override fun loadUserByUsername(name : String): UserDetails {
        logger.info(name)
        val user = repo.findByName(name)
        return User(user!!.name,passwordEncoder.encode(user.password),AuthorityUtils.NO_AUTHORITIES)
    }

从这里开始有趣,似乎代码从未运行过val user = repo.findByName(name)。最糟糕的是,没有异常被抛出,代码运行到该行,其余代码消失了。 出于沮丧,我决定伪造返回对象,以便可以通过这样的身份验证:

    override fun loadUserByUsername(name : String): UserDetails {
        logger.info(name)
        //val user = repo.findByName(name)
        logger.debug("asdkfhasdklfjhasdf")
        return User("string",passwordEncoder.encode("you"),AuthorityUtils.NO_AUTHORITIES)
    }

现在,终于可以得到一些例外了:

{
  "timestamp": "2018-11-08T18:08:29.541+0000",
  "status": 500,
  "error": "Internal Server Error",
  "message": "No accessor to set property @org.springframework.data.annotation.Id()private final java.lang.String com.sonnbh.jwt.User.id!",
  "path": "/user"
}

spring无法访问属性id的异常状态,因此我将id的类型从val更改为var

@Document(collection = "user")
data class User (
        var name : String,
        var password : String,
        var email : String,
        var type : String,
        var status : String,
        var balance : Int
){
    @Id var id : String = ObjectId.get().toHexString()
}

最后,我的应用程序按预期工作。但是,在尝试更深入地研究问题之后,我发现此问题仅发生在spring-boot v2.1.0上。我使用spring-boot v2.0.5的旧项目实际上在val id上运行良好。这使我提出了一个问题:

  1. 我对数据类User的旧实现是否正确?我只想防止从数据库或init读取对User.id的任何更改。我该怎么做才能改善?
  2. 为什么spring-boot v2.1无法像spring-boot v2.0.5那样访问属性?

2 个答案:

答案 0 :(得分:0)

只能回答第一部分;您可以尝试将ID声明移到构造函数之外?这样可以满足您仅在创建对象时进行初始化的要求,并且该对象仍然是只读的。

答案 1 :(得分:0)

2.1中的Spring数据。改变了处理实体中最终字段的方式。它不再使用反射来覆盖字段的不变性,这通常是好的。有几种方法可以解决该问题。

它们在这里描述:https://jira.spring.io/browse/DATACMNS-1374?focusedCommentId=182289&page=com.atlassian.jira.plugin.system.issuetabpanels%3Acomment-tabpanel#comment-182289

这是春季队的建议:

  
      
  1. 添加@PersistenceConstructor来构建设置不可变字段的实体。
  2.   
  3. 添加凋谢方法(MyEntity withXxx(…))以创建一个包含更改后的属性值的新实例。
  4.   
  5. 或者:使用Kotlin的数据类功能。基本上,这和凋灵方法一样。
  6.