Аутентификация с использованием jwt, как проверять http запросы - PullRequest
1 голос
/ 18 апреля 2020

Я пишу веб-приложение, используя весеннюю загрузку. Это на основе аутентификации jwt У меня есть модели Пользователь, Учитель, Студент, Курс. Учитель и ученик расширяют возможности пользователя

@Entity
public class User {
   @Id
   @GeneratedValue(strategy = GenerationType.IDENTITY)
   private Long id;
   private String username;
   @ManyToMany(fetch = FetchType.LAZY)
   @JoinTable(name = "user_roles",
            joinColumns = @JoinColumn(name = "user_id"),
            inverseJoinColumns = @JoinColumn(name = "role_id"))
   private Set<Role> roles = new HashSet<>();
   // Other fields and getters setters
}

@Entity
public class Course {
   @Id
   @GeneratedValue(strategy = GenerationType.IDENTITY)
   private Long id;   
   @ManyToOne
   @JoinColumn(name = "teacher_id", nullable = false)
   private Teacher teacher;

   @ManyToMany(mappedBy = "enrolledCourses")
   private Set<Student> students;
   // Other fields and getters setters
}

@Entity
public class Teacher extends User{
   @OneToMany(mappedBy = "teacher")
   private Set<Course> courses;
   // Other fields and getters setters
}


@Entity
public class Student extends User{
   @ManyToMany
   @JoinTable(
        name = "course_student",
        joinColumns = @JoinColumn(name = "student_id"),
        inverseJoinColumns = @JoinColumn(name = "course_id"))
   private Set<Course> enrolledCourses;
   // Other fields and getters setters
}

. Кроме того, у меня есть курс Api, в котором я реализовал публикацию, размещение, удаление, обновление, и эти методы должны быть доступны только для тех пользователей, которые являются учителями. Мой курс API выглядит следующим образом

@RestController
@RequestMapping("/teachers")
@PreAuthorize("hasRole('TEACHER')")
public class TeacherCourseController {

   @GetMapping("/{teacherId}/courses")
   public Set<Course> getCourse(@PathVariable("teacherId") Teacher teacher){
    // code
   }
   @PostMapping("/{teacherId}/courses")
   public Course createCourse(
        @PathVariable("teacherId") Long teacherId,
        @ModelAttribute CourseDto courseDto){
   // code
   }
   @PutMapping("/{teacherId}/courses/{courseId}")
   @JsonView(Views.IdName.class)
   public Course updateCourse(
        @ModelAttribute CourseDto courseDto,
        @PathVariable("courseId") Course courseFromDb){
    // code
   }
   @DeleteMapping("/{teacherId}/courses/{courseId}")
   public void getCourse(@PathVariable("courseId") Course course) throws IOException {
    // code
   }
}

URL моего API становится хуже проверьте, запрашивает ли учитель свои курсы, а не другие учителя. Спасибо

Ответы [ 2 ]

1 голос
/ 18 апреля 2020

Если у вас есть успешная конфигурация безопасности Spring:

  • веб-логин
  • генерация токена
  • передача токена в качестве заголовка в каждом вызове API

Вы должны иметь доступ к контексту безопасности Spring, чтобы получить электронное письмо пользователя, который вызывает вашу конечную точку отдыха:

Authentication auth = SecurityContextHolder.getContext().getAuthentication();
String name = auth.getName(); //get logged in username

С реальным адресом электронной почты (из-за вашего входа в систему до api invocation) и запрос к вашей базе данных, вы можете убедиться, что учитель запрашивает только его курсы, а также выводить сообщение об ошибке, если нет: у вас нет доступа к этому курсу.

Совет: список только моих курсов

Если есть и конечная точка только для простых учителей, не устанавливайте teacherId в качестве параметра:

http://localhost:8080/teacher/courses/{courseId}

Этот идентификатор учителя не требуется, поскольку Вы можете получить его (реальную электронную почту) учителя, используя контекст безопасности Spring, и искать курсы, используя инстинкт электронной почты учителя. ead teacherId

Совет: я администратор, и мне нужно просмотреть курсы всех моих преподавателей

В этом случае ваша конечная точка полностью действительна:

http://localhost:8080/teachers/{teacherId}/courses/{courseId}
1 голос
/ 18 апреля 2020

Почему бы не сделать курсы ресурсом верхнего уровня? У вас будет такой путь, как /courses{courseId}. В методе обработчика вы проверяете утверждение sub из токена JWT, который аутентифицировал запрос. Если заявка не соответствует идентификатору учителя преподавателя, проводящего курс, вы возвращаете ответ 403 Forbidden.

Несмотря на то, что курсы преподаются учителем, имеет смысл, что они должны быть на своем верхнем уровне. ресурс, потому что студенты могут перечислить их и подписаться на них.

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