JWT 是不是应该是一个单独的身份验证微服务,而不是与后端业务逻辑坐在一起?

Posted

技术标签:

【中文标题】JWT 是不是应该是一个单独的身份验证微服务,而不是与后端业务逻辑坐在一起?【英文标题】:Should JWT be a separate auth micro-service and not sit with the backend business logic?JWT 是否应该是一个单独的身份验证微服务,而不是与后端业务逻辑坐在一起? 【发布时间】:2020-03-15 19:49:03 【问题描述】:

我是微服务架构的新手,我正在使用 SpringBoot 构建应用程序并想为我的 API 添加 JWT 身份验证。

参考链接:https://dzone.com/articles/spring-boot-security-json-web-tokenjwt-hello-world

我想知道是否应该从业务微服务(BMS)中分离出身份验证/授权代码。所以每次对 BMS 的 rest API 调用都会依次调用 auth-microservice 进行验证。这是一个很好的做法还是会增加网络流量?

调用可能如下所示:

客户端 -> 业务应用程序 -> AuthMS -> 业务应用程序 -> 客户端

将其分开的原因是有些配置和代码与业务应用程序结合起来看起来不太好,但我不确定每次 API 调用所需的网络成本。

JWT 应用程序中的示例代码在不同的服务/服务器中运行是否有意义? :

import java.util.Objects;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.DisabledException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import com.javainuse.service.JwtUserDetailsService;
import com.javainuse.config.JwtTokenUtil;
import com.javainuse.model.JwtRequest;
import com.javainuse.model.JwtResponse;
@RestController
@CrossOrigin
public class JwtAuthenticationController 
@Autowired
private AuthenticationManager authenticationManager;
@Autowired
private JwtTokenUtil jwtTokenUtil;
@Autowired
private JwtUserDetailsService userDetailsService;
@RequestMapping(value = "/authenticate", method = RequestMethod.POST)
public ResponseEntity<?> createAuthenticationToken(@RequestBody JwtRequest authenticationRequest) throws Exception 
authenticate(authenticationRequest.getUsername(), authenticationRequest.getPassword());
final UserDetails userDetails = userDetailsService
.loadUserByUsername(authenticationRequest.getUsername());
final String token = jwtTokenUtil.generateToken(userDetails);
return ResponseEntity.ok(new JwtResponse(token));

private void authenticate(String username, String password) throws Exception 
try 
authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(username, password));
 catch (DisabledException e) 
throw new Exception("USER_DISABLED", e);
 catch (BadCredentialsException e) 
throw new Exception("INVALID_CREDENTIALS", e);



【问题讨论】:

【参考方案1】:

让您的 api 网关处理所有授权请求是一个很好的做法。 请求将通过 api 网关进行验证,然后才能访问微服务(业务逻辑所在的位置)。让您的网关处理以下事项:

(1) 在每个请求中验证令牌 (2) 阻止所有未经身份验证的服务请求

Check this out for more details

【讨论】:

所以我认为将其作为微服务分离是一种很好的做法,但我有疑问,网关如何了解传入的请求,因为它作为不同的微服务运行不同的端口 howtodoinjava.com/spring-cloud/spring-cloud-api-gateway-zuul这个链接有一切 我已经尝试过与 spring cloud api gateway zuul link 相同的示例,但我的请求失败,出现 401,未授权,有什么想法吗?我只是在尝试一个带有 springboot 的 zuul 基本示例,以了解通过网关到其他服务的路由,谢谢 卡了3天,什么都试了,清理项目解决了。

以上是关于JWT 是不是应该是一个单独的身份验证微服务,而不是与后端业务逻辑坐在一起?的主要内容,如果未能解决你的问题,请参考以下文章

使用 JWT 对单独的 API 微服务进行身份验证

使用 jwt 在微服务中进行身份验证

微服务中的 JWT 身份验证

在微服务环境中,任何生产者都应该能够验证 JWT 令牌吗?

使用 JWT 和 OpenID Connect 在微服务中进行客户端身份验证

在微服务架构的每个服务中验证访问令牌 (JWT)