1

Tomcat が組み込まれたスプリング ブート webApplication と、reactor の netServer を使用して「ハイブリッド」サーバーを開発し、Rest Api をスケールアップしようとしています。Spring コントローラーはなく、すべての着信要求は netServer によって処理されます。それでもなお、Spring Security を使用したログイン ページでユーザーを認証し、この認証を使用して、reactor netServer で着信要求をセキュリティで保護する機能を使用したいと考えています。

このチュートリアルリアクター サムメーラーに従って、netServer の実装を開始します。

ここに私の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()));
        }
    };

}

ハックは次のとおりです。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を保護するための最良の方法であるかどうかはわかりません)

リアクター netServer で Spring セキュリティを使用する簡単な方法はありますか ??? 私の最初の Web サイト バージョンは、多数の同時ユーザーを処理するために nodeJS で開発されました。JVM nio ソリューションを使用してリファクタリングしようとしています。スプリング/リアクター/ネットは、スケーラビリティの高いサーバーを持つための優れたソリューションですか、それともプレイのようなものを使用する必要があります! またはvertx.io?

どうもありがとう

4

1 に答える 1

1

NetServerJavaConfig@Beanメソッド内でブートストラップを試みましたか? 何かのようなもの:

@Configuration
@EnableReactor
class AppConfig {

  public Function<NetChannel, UserController> users() {
    return new UserControllerFactory();
  }

  @Bean
  public NetServer netServer(Environment env, Function<NetChannel, UserController> users) {
    return new TcpServerSpec(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(users.apply(ch));
      })
      .get();
  }

}

これにより、Spring Security サポートが維持され、ハンドラーを静的メソッドからの戻り値としてではなく、Bean として共有できるようになります。一般に、Reactor TCP アプリで行う必要があるほぼすべてのことは、Bean とインジェクションを使用しNetServerて、Bean 自体として返すことで実行できます。

于 2014-07-29T22:07:28.637 に答える