大致的认证交互流程:请求方调用获取session接口,获取sessionID和challenge,经过双方规定的规则,用challenge加密规定的密码后,再调用认证接口,认证成功则在接下来二十分钟可以调用本服务其他接口(调用则延长认证,二十分钟内未调用任何接口才视为超时)。若未认证或超时,则调用接口需要先认证。
刚开始的时候觉得这个认证机制很像session,但是考虑到调用本服务的是后端,不一定每次请求都会带相同的sessionID,因此放弃了通过获取sessionID来识别调用方的想法。而调用方也不会在后续请求中,传入本服务第一个接口(获取session)给出的sessionID,因此也不能通过这个sessionID来标识(实际上如果用sessionID标识,也很容易被截获)。
因此最后只能简单处理为识别调用方的IP,通过IP标识是否认证成功,但是对于后端服务而言,其实会有多个服务部署在同一机器上的情况,这个时候当A服务通过认证,则B服务不需要认证即可调用接口,也不是很合理,考虑到或许可以再获取port,但是只能获取到调用方的请求port,是随机的,(固定的port其实是监听port),所以确实是无法区分,因此这里暂时只识别IP。
controller:
@RestController
public class SecurityController {
@Autowired
private SecurityService securityService;
@PostMapping("/getSession")
public BaseResult<SessionInfoVO> getSession() {
SessionInfoBO sessionInfoBO = securityService.getSession();
return BaseResult.success(TypeTool.castToBean(sessionInfoBO,SessionInfoVO.class));
}
@PostMapping("/register")
public BaseResult register(@RequestBody RegisterInfoVO registerInfoVO, HttpServletRequest request) {
RegisterInfoBO registerInfoBO = TypeTool.castToBean(registerInfoVO,RegisterInfoBO.class);
String ip = securityService.getIpFromRequest(request);
registerInfoBO.setRequestIP(ip);
if(securityService.register(registerInfoBO)){
return BaseResult.success();
}
return BaseResult.error("0x111","register error");
}
}
跳过接口SecurityService 直接看SecurityServiceImpl
由于springMVC是单例模式,因此直接把需要存下来的session信息和注册认证信息作为类的变量即可,除非重启程序,它才会消失。
@Service
public class SecurityServiceImpl implements SecurityService {
private static final XxxLogger LOGGER = Xxx.getLogger(SecurityService.<