实战源码"/>
使用Spring Security和JWT保护REST API实战源码
设计REST API时,必须考虑如何保护REST API,在基于Spring的应用程序中,Spring Security是一种出色的身份验证和授权解决方案,它提供了几种保护REST API的选项。
最简单的方法是使用HTTP Basic,当你启动基于Spring Boot的应用程序时,默认情况下会激活它,这有利于开发,可在开发阶段经常使用,但不建议在生产环境中使用。
Spring Session(使用Spring Security)提供了一个简单的策略来创建和验证基于头的令牌(会话ID),它可以用于保护RESTful API。
除此之外,Spring Security OAuth(Spring Security下的子项目)提供OAuth授权的完整解决方案,包括OAuth2协议中定义的所有角色的实现,例如授权服务器,资源服务器,OAuth2客户端等,Spring Cloud在其子项目Spring Cloud Security中给OAuth2客户端增加了单点登录功能,在基于Spring Security OAuth的解决方案中,访问令牌的内容可以是签名的JWT令牌或不透明值,我们必须遵循标准OAuth2授权流程来获取访问令牌。
对于那些没有计划将自己API暴露给第三方应用程序的资源完全拥有者来说,基于JWT令牌的简单授权更简单合理(我们不需要管理第三方客户端应用程序的凭据)。
Spring Security本身并没有提供这样的选项,幸运的是,通过将我们的自定义过滤器混合到Spring Security Filter Chain中来实现它并不困难。在这篇文章中,我们将创建这样一个自定义JWT身份验证解决方案。
在此示例应用程序中,可以将基于自定义JWT令牌的身份验证流程指定为以下步骤:
1. 从身份验证端点获取基于JWT的令牌,例如/auth/signin。
2. 从身份验证结果中提取令牌。
3. 将HTTP标头Authorization值设置为Bearer jwt_token。
4. 然后发送一个访问受保护资源的请求。
5. 如果请求的资源受到保护,Spring Security将使用我们的自定义Filter来验证JWT令牌,并构建一个Authentication对象,把它放入SecurityContextHolder以完成身份验证流程。
6. 如果JWT令牌有效,它将把请求的资源返回给客户端。
生成项目框架
创建新Spring Boot项目的最快方法是使用Spring Initializr生成基本代码。
打开浏览器,转到,在Dependencies字段中,选择Web,Security,JPA,Lombok,然后单击Generate按钮或按ALT + ENTER键以生成项目框架代码。
等待一段时间下载生成的代码,完成后,将zip文件解压缩到本地系统。
打开你喜欢的IDE,例如Intellij IDEA,NetBeans IDE,然后导入它。
创建示例REST API
在此应用程序中,我们将公开车辆资源的REST API。
/vehiclesPOST {name:'title'}
/vehicles/{id}GET200, {id:'1', name:'title'}
/vehicles/{id}PUT {name:'title'}
/vehicles/{id}DELETE
创建JPA实体Vehicle。
@Entity @Table(name="vehicles") @Data @Builder @AllArgsConstructor @NoArgsConstructor public class Vehicle implements Serializable {@Id@GeneratedValue(strategy = GenerationType.AUTO)private Long id ;@Columnprivate String name; }
创建JPA存储库:
public interface VehicleRepository extends JpaRepository<Vehicle, Long> { }
创建一个Spring MVC basec Controller来公开REST API。
@RestController @RequestMapping("/v1/vehicles") public class VehicleController {private VehicleRepository vehicles;public VehicleController(VehicleRepository vehicles) {this.vehicles = vehicles;}@GetMapping("")public ResponseEntity all() {return ok(this.vehicles.findAll());}@PostMapping("")public ResponseEntity save(@RequestBody VehicleForm form, HttpServletRequest request) {Vehicle saved = this.vehicles.save(Vehicle.builder().name(form.getName()).build());return created(ServletUriComponentsBuilder.fromContextPath(request).path("/v1/vehicles/{id}").buildAndExpand(saved.getId()).toUri()).build();}@GetMapping("/{id}")public ResponseEntity get(@P
更多推荐
使用Spring Security和JWT保护REST API实战源码
发布评论