我尝试使用带有嵌入式tomcat的spring boot webApplication和来自reactor的netServer开发一个“混合”服务器,以扩大我的Rest Api。没有 Spring 控制器,所有传入的请求都由 netServer 处理。无论如何,我都希望有一个使用 spring security 的登录页面,记住我的设施来验证用户并使用此身份验证来保护 reactor netServer 上的传入请求。
根据本教程reactor thumbmailer,我开始实现 netServer
这是我的网络服务器:
NetServer<FullHttpRequest, FullHttpResponse> server = new TcpServerSpec<FullHttpRequest, FullHttpResponse>(NettyTcpServer.class)
.env(env)
.dispatcher("sync")
.listen(8080)
.options(opts)
.consume(ch -> {
// attach an error handler
ch.when(Throwable.class, UserController.errorHandler(ch));
// filter requests by URI
Stream<FullHttpRequest> in = ch.in();
// serve image thumbnail to browser
in.filter((FullHttpRequest req) -> req.getUri().startsWith(UserController.GET_USER_PROFILE))
.consume(UserController.getUserProfile(ch));
})
.get();
因此,当用户尝试加载他的个人资料时,传入的请求由 userController 处理:
public static Consumer<FullHttpRequest> getUserProfile(NetChannel<FullHttpRequest, FullHttpResponse> channel) {
UserService userService = StaticContextAccessor.getBean(UserService.class);
return req -> {
try {
LoginDTO login = RestApiUtils.parseJson(LoginDTO.class, RestApiUtils.getJsonContent(req));
DefaultFullHttpResponse resp = new DefaultFullHttpResponse(HTTP_1_1, OK);
String result = userService.loadUserProfile(login);
resp.headers().set(CONTENT_TYPE, "application/json");
resp.headers().set(CONTENT_LENGTH, result.length());
resp.content().writeBytes(result.getBytes());
channel.send(resp);
} catch (Exception e) {
channel.send(badRequest(e.getMessage()));
}
};
}
这是 hack:getUserProfile 是一个静态方法,所以我不能使用 GlobalMethodSecurity 来保护它。然后我使用 StaticContextAccessor 在这个控制器中注入一个 userService :
@Component
public class StaticContextAccessor {
private static StaticContextAccessor instance;
@Autowired
private ApplicationContext applicationContext;
@PostConstruct
public void registerInstance() {
instance = this;
}
public static <T> T getBean(Class<T> clazz) {
return instance.applicationContext.getBean(clazz);
}
}
用户服务:
@Service
@PreAuthorize("true")
public class UserServiceImpl implements UserService{
public String loadUserProfile(LoginDTO login){
//TODO load profile in mongo
return new GsonBuilder().create().toJson(login);
}
}
该服务由spring管理,所以我想我可以在它上面使用spring GlobalMethodSecurity(我仍在开发这部分,但我不确定这是保护我的netServer的最佳方式)
有没有更简单的方法在 reactor netServer 上使用 Spring 安全性???我的第一个网站版本是使用 nodeJS 开发的,以处理许多并发用户,我尝试使用 JVM nio 解决方案对其进行重构。那么 spring / reactor / netty 是拥有高度可扩展服务器的一个很好的解决方案,还是我应该使用类似 play 的东西!或 vertx.io ?
太感谢了