使用jwt进行身份验证如何验证http请求

时间:2020-04-18 15:30:55

标签: spring-boot http security authentication jwt

我正在使用Spring Boot编写Web应用程序。它是基于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
   }
}

我的api网址越来越糟,看起来像这样http://localhost:8080/teachers/ {teacherId} / courses / {courseId} 我如何检查老师是否要求他的课程而不是其他老师。谢谢

2 个答案:

答案 0 :(得分:1)

为什么不使课程成为顶级资源?您将拥有类似pdf = ( df.select( sf.to_date("date", "d MMMMM yyyy").alias("new_date"), "date", "count", ) .orderBy("new_date") .toPandas() ) pdf.plot.line(x="new_date", y="count") 的路径。在处理程序方法中,您检查来自JWT令牌的/courses{courseId}声明,该声明对请求进行了身份验证。如果索偿与提供课程的老师的老师编号不符,您将返回sub答复。

即使课程是由老师教授的,也应该将其作为自己的顶级资源,因为学生可以列出并注册。

答案 1 :(得分:1)

如果您具有成功的spring安全性配置:

  • 网络登录
  • 代币生成
  • 在每个api调用中将令牌作为标头传递

您必须有权访问spring安全上下文,以获取正在调用其余端点的用户的电子邮件:

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

使用真实的电子邮件(由于api调用前您的网络登录)和对数据库的查询,您可以确保老师仅请求其课程,如果没有,则显示并显示错误:您无权访问此课程

建议:仅列出我的课程

如果is和endpoint仅用于简单教师,请不要将 teacherId 设置为参数:

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

不需要此TeacherId,因为您可以使用Spring Security上下文获取该教师的ID(真实电子邮件),并使用Teacher电子邮件而不是TeacherId来搜索课程

建议:我是管理员,我需要查看我所有老师的课程

在这种情况下,您的端点完全有效:

http://localhost:8080/teachers/{teacherId}/courses/{courseId}