Spring boot 2.1.0: изменение безопасности с классом данных kotlin? - PullRequest
0 голосов
/ 08 ноября 2018

Эта проблема делает меня физически больным.

Шутка в сторону, я пытаюсь добавить слой аутентификации в свое веб-приложение, используя Spring-Boot с плагином безопасности. Вот мой класс данных.

@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)
    }

Здесь, где начинается самое интересное, кажется, что код никогда не запускается pass 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? Я просто хочу предотвратить любое изменение User.id после его чтения из базы данных или инициализации. Что я могу сделать, чтобы улучшить?
  2. Почему spring-boot v2.1 не может получить доступ к свойству, как spring-boot v2.0.5 сделал?

Ответы [ 2 ]

0 голосов
/ 05 июня 2019

Spring Data в 2.1. изменил способ работы с конечными полями в сущностях. Он больше не использует отражение, чтобы переопределить неизменность полей, что в целом хорошо. Есть несколько способов справиться с проблемой.

Они описаны здесь: https://jira.spring.io/browse/DATACMNS-1374?focusedCommentId=182289&page=com.atlassian.jira.plugin.system.issuetabpanels%3Acomment-tabpanel#comment-182289

Вот что рекомендуют ребята из Spring:

  1. Добавьте @PersistenceConstructor для создания сущности, которая устанавливает неизменяемые поля.
  2. Добавьте методы вихря (MyEntity withXxx (…)), чтобы создать новый экземпляр, содержащий измененное значение свойства.
  3. В качестве альтернативы: используйте функцию класса данных Kotlin. Это в основном будет делать то же самое, что и методы с засохшими.
0 голосов
/ 09 ноября 2018

Могу ответить только на первую часть;Вы могли бы попытаться переместить объявление ID, чтобы быть отдельно от конструктора?Это удовлетворит ваше требование инициализации только при создании объекта, и он все еще будет доступен только для чтения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...