Spring Security WebFlux - «AuthenticationCredentialsNotFoundException: не аутентифицирован» с пользовательской аутентификацией EntryPoint - PullRequest
0 голосов
/ 24 сентября 2019

Я пытаюсь настроить Spring Security в реактивном приложении Spring Boot с внешним интерфейсом Vuejs, который перенаправляет пользователей к внешнему провайдеру OpenID (для проверки подлинности) в случае неаутентификации.После проверки подлинности пользователей с помощью поставщика OpenID и перенаправления обратно в приложение (веб-интерфейс) будет создан UsernamePasswordAuthenticationToken (Authentication) на основе ответа поставщика OpenID, который будет проверен вручную.

Однако при этом приложение, похоже, не может обнаружить, что пользователь прошел проверку подлинности, поскольку AuthenticationEntryPoint все еще вызывается со следующим исключением, а preAuthenticationFilter (показанный ниже) по-прежнему вызывается повторно из-забудучи аутентифицированным.

org.springframework.security.authentication.AuthenticationCredentialsNotFoundException: Not Authenticated
    at org.springframework.security.web.server.authorization.ExceptionTranslationWebFilter.commenceAuthentication(ExceptionTranslationWebFilter.java:72)
    at org.springframework.security.web.server.authorization.ExceptionTranslationWebFilter.lambda$filter$1(ExceptionTranslationWebFilter.java:44)
    at reactor.core.publisher.Mono.lambda$onErrorResume$25(Mono.java:3146)
    at reactor.core.publisher.FluxOnErrorResume$ResumeSubscriber.onError(FluxOnErrorResume.java:88)
    at reactor.core.publisher.Operators$MultiSubscriptionSubscriber.onError(Operators.java:1748)
    at reactor.core.publisher.MonoFlatMap$FlatMapMain.onError(MonoFlatMap.java:165)
    at reactor.core.publisher.Operators$MultiSubscriptionSubscriber.onError(Operators.java:1748)
    at reactor.core.publisher.Operators.error(Operators.java:181)
    at reactor.core.publisher.MonoError.subscribe(MonoError.java:52)
    at reactor.core.publisher.MonoDefer.subscribe(MonoDefer.java:52)
    at reactor.core.publisher.Mono.subscribe(Mono.java:3852)
    at reactor.core.publisher.FluxSwitchIfEmpty$SwitchIfEmptySubscriber.onComplete(FluxSwitchIfEmpty.java:75)
    at reactor.core.publisher.FluxFilter$FilterSubscriber.onComplete(FluxFilter.java:160)
    at reactor.core.publisher.FluxDefaultIfEmpty$DefaultIfEmptySubscriber.onComplete(FluxDefaultIfEmpty.java:98)
    at reactor.core.publisher.MonoNext$NextSubscriber.onComplete(MonoNext.java:96)
    at reactor.core.publisher.MonoNext$NextSubscriber.onNext(MonoNext.java:77)
    at reactor.core.publisher.FluxConcatMap$ConcatMapImmediate.innerNext(FluxConcatMap.java:275)
    at reactor.core.publisher.FluxConcatMap$ConcatMapInner.onNext(FluxConcatMap.java:849)
    at reactor.core.publisher.Operators$MonoSubscriber.complete(Operators.java:1515)
    at reactor.core.publisher.MonoFlatMap$FlatMapInner.onNext(MonoFlatMap.java:241)
    at reactor.core.publisher.Operators$MonoSubscriber.complete(Operators.java:1515)
    at reactor.core.publisher.FluxDefaultIfEmpty$DefaultIfEmptySubscriber.onComplete(FluxDefaultIfEmpty.java:100)
    at reactor.core.publisher.FluxMapFuseable$MapFuseableSubscriber.onComplete(FluxMapFuseable.java:144)
    at reactor.core.publisher.FluxMapFuseable$MapFuseableSubscriber.onComplete(FluxMapFuseable.java:144)
    at reactor.core.publisher.FluxFilterFuseable$FilterFuseableSubscriber.onComplete(FluxFilterFuseable.java:166)
    at reactor.core.publisher.MonoFlatMap$FlatMapMain.secondComplete(MonoFlatMap.java:189)
    at reactor.core.publisher.MonoFlatMap$FlatMapInner.onComplete(MonoFlatMap.java:260)
    at reactor.core.publisher.MonoFlatMap$FlatMapMain.onNext(MonoFlatMap.java:141)
    at reactor.core.publisher.FluxMap$MapSubscriber.onNext(FluxMap.java:114)
    at reactor.core.publisher.Operators$MonoSubscriber.complete(Operators.java:1515)
    at reactor.core.publisher.MonoProcessor.subscribe(MonoProcessor.java:457)
    at reactor.core.publisher.MonoMap.subscribe(MonoMap.java:55)
    at reactor.core.publisher.MonoFlatMap.subscribe(MonoFlatMap.java:60)
    at reactor.core.publisher.MonoFlatMap$FlatMapMain.onNext(MonoFlatMap.java:150)
    at reactor.core.publisher.FluxFilterFuseable$FilterFuseableSubscriber.onNext(FluxFilterFuseable.java:113)
    at reactor.core.publisher.Operators$ScalarSubscription.request(Operators.java:2071)
    at reactor.core.publisher.FluxFilterFuseable$FilterFuseableSubscriber.request(FluxFilterFuseable.java:185)
    at reactor.core.publisher.MonoFlatMap$FlatMapMain.onSubscribe(MonoFlatMap.java:103)
    at reactor.core.publisher.FluxFilterFuseable$FilterFuseableSubscriber.onSubscribe(FluxFilterFuseable.java:82)
    at reactor.core.publisher.MonoCurrentContext.subscribe(MonoCurrentContext.java:35)
    at reactor.core.publisher.MonoFilterFuseable.subscribe(MonoFilterFuseable.java:47)
    at reactor.core.publisher.MonoFlatMap.subscribe(MonoFlatMap.java:60)
    at reactor.core.publisher.MonoFilterFuseable.subscribe(MonoFilterFuseable.java:47)
    at reactor.core.publisher.MonoMapFuseable.subscribe(MonoMapFuseable.java:59)
    at reactor.core.publisher.MonoMapFuseable.subscribe(MonoMapFuseable.java:59)
    at reactor.core.publisher.MonoDefaultIfEmpty.subscribe(MonoDefaultIfEmpty.java:37)
    at reactor.core.publisher.MonoFlatMap$FlatMapMain.onNext(MonoFlatMap.java:150)
    at reactor.core.publisher.FluxMapFuseable$MapFuseableSubscriber.onNext(FluxMapFuseable.java:121)
    at reactor.core.publisher.FluxFilterFuseable$FilterFuseableSubscriber.onNext(FluxFilterFuseable.java:113)
    at reactor.core.publisher.Operators$ScalarSubscription.request(Operators.java:2071)
    at reactor.core.publisher.FluxFilterFuseable$FilterFuseableSubscriber.request(FluxFilterFuseable.java:185)
    at reactor.core.publisher.FluxMapFuseable$MapFuseableSubscriber.request(FluxMapFuseable.java:162)
    at reactor.core.publisher.MonoFlatMap$FlatMapMain.onSubscribe(MonoFlatMap.java:103)
    at reactor.core.publisher.FluxMapFuseable$MapFuseableSubscriber.onSubscribe(FluxMapFuseable.java:90)
    at reactor.core.publisher.FluxFilterFuseable$FilterFuseableSubscriber.onSubscribe(FluxFilterFuseable.java:82)
    at reactor.core.publisher.MonoJust.subscribe(MonoJust.java:54)
    at reactor.core.publisher.MonoFilterFuseable.subscribe(MonoFilterFuseable.java:47)
    at reactor.core.publisher.MonoMapFuseable.subscribe(MonoMapFuseable.java:59)
    at reactor.core.publisher.MonoFlatMap.subscribe(MonoFlatMap.java:60)
    at reactor.core.publisher.Mono.subscribe(Mono.java:3852)
    at reactor.core.publisher.FluxConcatMap$ConcatMapImmediate.drain(FluxConcatMap.java:442)
    at reactor.core.publisher.FluxConcatMap$ConcatMapImmediate.onSubscribe(FluxConcatMap.java:212)
    at reactor.core.publisher.FluxIterable.subscribe(FluxIterable.java:139)
    at reactor.core.publisher.FluxIterable.subscribe(FluxIterable.java:63)
    at reactor.core.publisher.FluxConcatMap.subscribe(FluxConcatMap.java:121)
    at reactor.core.publisher.MonoNext.subscribe(MonoNext.java:40)
    at reactor.core.publisher.MonoDefaultIfEmpty.subscribe(MonoDefaultIfEmpty.java:37)
    at reactor.core.publisher.MonoFilter.subscribe(MonoFilter.java:46)
    at reactor.core.publisher.MonoSwitchIfEmpty.subscribe(MonoSwitchIfEmpty.java:44)
    at reactor.core.publisher.MonoFlatMap.subscribe(MonoFlatMap.java:60)
    at reactor.core.publisher.MonoSwitchIfEmpty.subscribe(MonoSwitchIfEmpty.java:44)
    at reactor.core.publisher.MonoDefer.subscribe(MonoDefer.java:52)
    at reactor.core.publisher.MonoOnErrorResume.subscribe(MonoOnErrorResume.java:44)
    at reactor.core.publisher.MonoDefer.subscribe(MonoDefer.java:52)
    at reactor.core.publisher.Mono.subscribe(Mono.java:3852)
    at reactor.core.publisher.MonoIgnoreThen$ThenIgnoreMain.drain(MonoIgnoreThen.java:172)
    at reactor.core.publisher.MonoIgnoreThen.subscribe(MonoIgnoreThen.java:56)
    at reactor.core.publisher.Mono.subscribe(Mono.java:3852)
    at reactor.core.publisher.FluxSwitchIfEmpty$SwitchIfEmptySubscriber.onComplete(FluxSwitchIfEmpty.java:75)
    at reactor.core.publisher.FluxFilter$FilterSubscriber.onComplete(FluxFilter.java:160)
    at reactor.core.publisher.FluxSwitchIfEmpty$SwitchIfEmptySubscriber.onComplete(FluxSwitchIfEmpty.java:78)
    at reactor.core.publisher.Operators$ScalarSubscription.request(Operators.java:2073)
    at reactor.core.publisher.Operators$MultiSubscriptionSubscriber.set(Operators.java:1879)
    at reactor.core.publisher.Operators$MultiSubscriptionSubscriber.onSubscribe(Operators.java:1753)
    at reactor.core.publisher.MonoJust.subscribe(MonoJust.java:54)
    at reactor.core.publisher.Mono.subscribe(Mono.java:3852)
    at reactor.core.publisher.FluxSwitchIfEmpty$SwitchIfEmptySubscriber.onComplete(FluxSwitchIfEmpty.java:75)
    at reactor.core.publisher.MonoNext$NextSubscriber.onComplete(MonoNext.java:96)
    at reactor.core.publisher.FluxFilter$FilterSubscriber.onComplete(FluxFilter.java:160)
    at reactor.core.publisher.FluxFlatMap$FlatMapMain.checkTerminated(FluxFlatMap.java:794)
    at reactor.core.publisher.FluxFlatMap$FlatMapMain.drainLoop(FluxFlatMap.java:560)
    at reactor.core.publisher.FluxFlatMap$FlatMapMain.drain(FluxFlatMap.java:540)
    at reactor.core.publisher.FluxFlatMap$FlatMapMain.onComplete(FluxFlatMap.java:426)
    at reactor.core.publisher.FluxIterable$IterableSubscription.slowPath(FluxIterable.java:265)
    at reactor.core.publisher.FluxIterable$IterableSubscription.request(FluxIterable.java:201)
    at reactor.core.publisher.FluxFlatMap$FlatMapMain.onSubscribe(FluxFlatMap.java:335)
    at reactor.core.publisher.FluxIterable.subscribe(FluxIterable.java:139)
    at reactor.core.publisher.FluxIterable.subscribe(FluxIterable.java:63)
    at reactor.core.publisher.FluxFlatMap.subscribe(FluxFlatMap.java:97)
    at reactor.core.publisher.FluxFilter.subscribe(FluxFilter.java:53)
    at reactor.core.publisher.MonoNext.subscribe(MonoNext.java:40)
    at reactor.core.publisher.MonoSwitchIfEmpty.subscribe(MonoSwitchIfEmpty.java:44)
    at reactor.core.publisher.MonoFilter.subscribe(MonoFilter.java:46)
    at reactor.core.publisher.MonoSwitchIfEmpty.subscribe(MonoSwitchIfEmpty.java:44)
    at reactor.core.publisher.MonoMap.subscribe(MonoMap.java:55)
    at reactor.core.publisher.MonoFlatMap.subscribe(MonoFlatMap.java:60)
    at reactor.core.publisher.MonoFlatMap.subscribe(MonoFlatMap.java:60)
    at reactor.core.publisher.MonoDefer.subscribe(MonoDefer.java:52)
    at reactor.core.publisher.MonoFlatMap$FlatMapMain.onNext(MonoFlatMap.java:150)
    at reactor.core.publisher.Operators$MonoSubscriber.complete(Operators.java:1515)
    at reactor.core.publisher.FluxDefaultIfEmpty$DefaultIfEmptySubscriber.onComplete(FluxDefaultIfEmpty.java:100)
    at reactor.core.publisher.FluxMap$MapSubscriber.onComplete(FluxMap.java:136)
    at reactor.core.publisher.FluxMap$MapSubscriber.onComplete(FluxMap.java:136)
    at reactor.core.publisher.FluxFilter$FilterSubscriber.onComplete(FluxFilter.java:160)
    at reactor.core.publisher.FluxMap$MapConditionalSubscriber.onComplete(FluxMap.java:262)
    at reactor.core.publisher.Operators$MonoSubscriber.complete(Operators.java:1516)
    at reactor.core.publisher.MonoProcessor.subscribe(MonoProcessor.java:457)
    at reactor.core.publisher.MonoMap.subscribe(MonoMap.java:52)
    at reactor.core.publisher.MonoFilter.subscribe(MonoFilter.java:46)
    at reactor.core.publisher.MonoMap.subscribe(MonoMap.java:55)
    at reactor.core.publisher.MonoMap.subscribe(MonoMap.java:55)
    at reactor.core.publisher.MonoDefaultIfEmpty.subscribe(MonoDefaultIfEmpty.java:37)
    at reactor.core.publisher.MonoFlatMap.subscribe(MonoFlatMap.java:60)
    at reactor.core.publisher.MonoDefer.subscribe(MonoDefer.java:52)
    at reactor.core.publisher.MonoDefer.subscribe(MonoDefer.java:52)
    at reactor.core.publisher.Mono.subscribe(Mono.java:3852)
    at reactor.core.publisher.MonoIgnoreThen$ThenIgnoreMain.drain(MonoIgnoreThen.java:172)
    at reactor.core.publisher.MonoIgnoreThen.subscribe(MonoIgnoreThen.java:56)
    at reactor.core.publisher.Mono.subscribe(Mono.java:3852)
    at reactor.core.publisher.FluxSwitchIfEmpty$SwitchIfEmptySubscriber.onComplete(FluxSwitchIfEmpty.java:75)
    at reactor.core.publisher.MonoFlatMap$FlatMapMain.onNext(MonoFlatMap.java:141)
    at reactor.core.publisher.FluxFilterFuseable$FilterFuseableSubscriber.onNext(FluxFilterFuseable.java:113)
    at reactor.core.publisher.Operators$ScalarSubscription.request(Operators.java:2071)
    at reactor.core.publisher.FluxFilterFuseable$FilterFuseableSubscriber.request(FluxFilterFuseable.java:185)
    at reactor.core.publisher.MonoFlatMap$FlatMapMain.onSubscribe(MonoFlatMap.java:103)
    at reactor.core.publisher.FluxFilterFuseable$FilterFuseableSubscriber.onSubscribe(FluxFilterFuseable.java:82)
    at reactor.core.publisher.MonoJust.subscribe(MonoJust.java:54)
    at reactor.core.publisher.MonoFilterFuseable.subscribe(MonoFilterFuseable.java:47)
    at reactor.core.publisher.MonoFlatMap.subscribe(MonoFlatMap.java:60)
    at reactor.core.publisher.MonoSwitchIfEmpty.subscribe(MonoSwitchIfEmpty.java:44)
    at reactor.core.publisher.MonoFlatMap.subscribe(MonoFlatMap.java:60)
    at reactor.core.publisher.MonoDefer.subscribe(MonoDefer.java:52)
    at reactor.core.publisher.MonoSubscriberContext.subscribe(MonoSubscriberContext.java:47)
    at reactor.core.publisher.MonoDefer.subscribe(MonoDefer.java:52)
    at reactor.core.publisher.MonoDefer.subscribe(MonoDefer.java:52)
    at reactor.core.publisher.MonoDefer.subscribe(MonoDefer.java:52)
    at reactor.core.publisher.MonoSubscriberContext.subscribe(MonoSubscriberContext.java:47)
    at reactor.core.publisher.MonoDefer.subscribe(MonoDefer.java:52)
    at reactor.core.publisher.MonoDefer.subscribe(MonoDefer.java:52)
    at reactor.core.publisher.MonoFlatMap$FlatMapMain.onNext(MonoFlatMap.java:150)
    at reactor.core.publisher.FluxMapFuseable$MapFuseableSubscriber.onNext(FluxMapFuseable.java:121)
    at reactor.core.publisher.FluxMapFuseable$MapFuseableSubscriber.onNext(FluxMapFuseable.java:121)
    at reactor.core.publisher.Operators$MonoSubscriber.complete(Operators.java:1515)
    at reactor.core.publisher.MonoFlatMap$FlatMapInner.onNext(MonoFlatMap.java:241)
    at reactor.core.publisher.Operators$MonoSubscriber.complete(Operators.java:1515)
    at reactor.core.publisher.MonoCollectList$MonoCollectListSubscriber.onComplete(MonoCollectList.java:121)
    at reactor.core.publisher.FluxIterable$IterableSubscription.fastPath(FluxIterable.java:333)
    at reactor.core.publisher.FluxIterable$IterableSubscription.request(FluxIterable.java:198)
    at reactor.core.publisher.MonoCollectList$MonoCollectListSubscriber.onSubscribe(MonoCollectList.java:72)
    at reactor.core.publisher.FluxIterable.subscribe(FluxIterable.java:139)
    at reactor.core.publisher.FluxIterable.subscribe(FluxIterable.java:63)
    at reactor.core.publisher.MonoCollectList.subscribe(MonoCollectList.java:40)
    at reactor.core.publisher.MonoFlatMap$FlatMapMain.onNext(MonoFlatMap.java:150)
    at reactor.core.publisher.FluxSwitchIfEmpty$SwitchIfEmptySubscriber.onNext(FluxSwitchIfEmpty.java:67)
    at reactor.core.publisher.MonoNext$NextSubscriber.onNext(MonoNext.java:76)
    at reactor.core.publisher.FluxFilterWhen$FluxFilterWhenSubscriber.drain(FluxFilterWhen.java:295)
    at reactor.core.publisher.FluxFilterWhen$FluxFilterWhenSubscriber.onNext(FluxFilterWhen.java:134)
    at reactor.core.publisher.FluxIterable$IterableSubscription.slowPath(FluxIterable.java:243)
    at reactor.core.publisher.FluxIterable$IterableSubscription.request(FluxIterable.java:201)
    at reactor.core.publisher.FluxFilterWhen$FluxFilterWhenSubscriber.onSubscribe(FluxFilterWhen.java:194)
    at reactor.core.publisher.FluxIterable.subscribe(FluxIterable.java:139)
    at reactor.core.publisher.FluxIterable.subscribe(FluxIterable.java:63)
    at reactor.core.publisher.FluxFilterWhen.subscribe(FluxFilterWhen.java:69)
    at reactor.core.publisher.MonoNext.subscribe(MonoNext.java:40)
    at reactor.core.publisher.MonoSwitchIfEmpty.subscribe(MonoSwitchIfEmpty.java:44)
    at reactor.core.publisher.MonoFlatMap.subscribe(MonoFlatMap.java:60)
    at reactor.core.publisher.MonoMapFuseable.subscribe(MonoMapFuseable.java:59)
    at reactor.core.publisher.MonoMapFuseable.subscribe(MonoMapFuseable.java:59)
    at reactor.core.publisher.MonoFlatMap.subscribe(MonoFlatMap.java:60)
    at reactor.core.publisher.MonoDefer.subscribe(MonoDefer.java:52)
    at reactor.core.publisher.MonoPeekTerminal.subscribe(MonoPeekTerminal.java:61)
    at reactor.core.publisher.MonoPeekFuseable.subscribe(MonoPeekFuseable.java:74)
    at reactor.core.publisher.MonoDefer.subscribe(MonoDefer.java:52)
    at reactor.core.publisher.MonoDefer.subscribe(MonoDefer.java:52)
    at reactor.core.publisher.MonoOnErrorResume.subscribe(MonoOnErrorResume.java:44)
    at reactor.core.publisher.MonoOnErrorResume.subscribe(MonoOnErrorResume.java:44)
    at reactor.core.publisher.MonoPeekTerminal.subscribe(MonoPeekTerminal.java:61)
    at reactor.core.publisher.MonoOnErrorResume.subscribe(MonoOnErrorResume.java:44)
    at reactor.core.publisher.Mono.subscribe(Mono.java:3852)
    at reactor.core.publisher.MonoIgnoreThen$ThenIgnoreMain.drain(MonoIgnoreThen.java:172)
    at reactor.core.publisher.MonoIgnoreThen.subscribe(MonoIgnoreThen.java:56)
    at reactor.core.publisher.MonoPeekFuseable.subscribe(MonoPeekFuseable.java:70)
    at reactor.core.publisher.MonoPeekTerminal.subscribe(MonoPeekTerminal.java:61)
    at reactor.netty.http.server.HttpServerHandle.onStateChange(HttpServerHandle.java:64)
    at reactor.netty.tcp.TcpServerBind$ChildObserver.onStateChange(TcpServerBind.java:226)
    at reactor.netty.http.server.HttpServerOperations.onInboundNext(HttpServerOperations.java:442)
    at reactor.netty.channel.ChannelOperationsHandler.channelRead(ChannelOperationsHandler.java:91)
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:374)
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:360)
    at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:352)
    at reactor.netty.http.server.HttpTrafficHandler.channelRead(HttpTrafficHandler.java:161)
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:374)
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:360)
    at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:352)
    at io.netty.channel.CombinedChannelDuplexHandler$DelegatingChannelHandlerContext.fireChannelRead(CombinedChannelDuplexHandler.java:438)
    at io.netty.handler.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:328)
    at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:302)
    at io.netty.channel.CombinedChannelDuplexHandler.channelRead(CombinedChannelDuplexHandler.java:253)
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:374)
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:360)
    at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:352)
    at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1421)
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:374)
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:360)
    at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:930)
    at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:163)
    at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:697)
    at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:632)
    at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:549)
    at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:511)
    at io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:918)
    at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74)
    at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
    at java.base/java.lang.Thread.run(Thread.java:835)
Caused by: org.springframework.security.access.AccessDeniedException: Access Denied
    at org.springframework.security.authorization.ReactiveAuthorizationManager.lambda$verify$1(ReactiveAuthorizationManager.java:53)
    at reactor.core.publisher.MonoDefer.subscribe(MonoDefer.java:44)
    ... 214 more

До сих пор мне удалось перенаправить пользователей к внешнему провайдеру OpenID для аутентификации, используя следующую AuthenticationEntryPoint.А также возможность перенаправления обратно во внешний интерфейс, если пользователь может войти в систему поставщика OpenID.

@Component
public class OpenIDAuthenticationEntryPoint implements ServerAuthenticationEntryPoint {
  @Autowired
  private OpenIdUtil openIdUtil;

  @Override
  public Mono<Void> commence(ServerWebExchange serverWebExchange, AuthenticationException e) {
    e.printStackTrace();
    return openIdUtil.authRequest(serverWebExchange); // invoke openid function
  }
}

Класс OpenIdUtil (со ссылкой из SampleConsumer из openid4java)

Log4j2
@Service
public class OpenIdUtil {
  private ConsumerManager manager;

  public OpenIdUtil() {
    // instantiate a ConsumerManager object
    manager = new ConsumerManager();
  }

  /**  placing the authentication request  **/
  public Mono<Void> authRequest(ServerWebExchange serverWebExchange) {
    System.out.println("AUTH-REQUEST");
    try
    {
      // configure the return_to URL where your application will receive the authentication responses from the OpenID provider
      String returnToUrl = "<return url>"; 

      // perform discovery on the user-supplied identifier
      List discoveries = manager.discover("<the url of the external openid provider>");

      // attempt to associate with the OpenID provider and retrieve one service endpoint for authentication
      DiscoveryInformation discovered = manager.associate(discoveries);

      // store the discovery information in the user's session
      serverWebExchange.getSession().map(session -> {
        session.getAttributes().put("openid-disc", discovered);
        return session;
      }).subscribe();

      // obtain a AuthRequest message to be sent to the OpenID provider
      AuthRequest authReq = manager.authenticate(discovered, returnToUrl);

      serverWebExchange.getResponse().setStatusCode(HttpStatus.TEMPORARY_REDIRECT);
      serverWebExchange.getResponse().getHeaders().setLocation(URI.create(authReq.getDestinationUrl(true)));
      return serverWebExchange.getResponse().setComplete();
    }
    catch (OpenIDException e)
    {
      // present error to the user
      e.printStackTrace();
    }
    return null;
  }

  /** processing the authentication response **/
  String verifyResponse(ServerWebExchange serverWebExchange) {

    try
    {
      // extract the parameters from the authentication response (which comes in as a HTTP request from the OpenID provider)
      MultiValueMap<String, String> queryParams = serverWebExchange.getRequest().getQueryParams();
      ParameterList response = new ParameterList(queryParams.toSingleValueMap());

      // retrieve the previously stored discovery information
      final DiscoveryInformation[] discovered = new DiscoveryInformation[1];
      serverWebExchange.getSession().map(session -> discovered[0] = session.getAttribute("openid-disc")).subscribe();

      // extract the receiving URL from the HTTP request
      String receivingURL = serverWebExchange.getRequest().getURI().toString();
      // verify the response; ConsumerManager needs to be the same (static) instance used to place the authentication request
      VerificationResult verification = manager.verify(receivingURL, response, discovered[0]);

      // examine the verification result and extract the verified identifier
      Identifier verified = verification.getVerifiedId();

      if (verified != null)
      {
        return verified.getIdentifier();  // success
      }
    }
    catch (OpenIDException e)
    {
      // present error to the user
    e.printStackTrace();
    }

    return null;
  }

}

Я также создал пользовательский ReactiveAuthenticationManager для ручного выполнения «аутентификации» (ссылаясь на пример Spring Webflux JWT - https://github.com/heesuk-ahn/spring-webflux-jwt-auth-example)

@Component
public class OpenIDReactiveAuthenticationManager implements ReactiveAuthenticationManager {
  @Override
  public Mono<Authentication> authenticate(Authentication authentication) {
    return Mono.just(authentication);
  }
}

и ServerAuthenticationConverter для проверки ответа аутентификации OpenId, поступающего от AuthenticationFilter ServerWebExchange.

@Component
public class PreAuthenticationConverter implements ServerAuthenticationConverter {

  @Autowired
  private OpenIdUtil openIdUtil;

  @Override
  public Mono<Authentication> convert(ServerWebExchange serverWebExchange) {
    try {
      String user = URI.create(openIdUtil.verifyResponse(serverWebExchange)).getPath();
      // extract credentials here
      if (!user.isEmpty()){
        SimpleGrantedAuthority authority = new SimpleGrantedAuthority("ROLE_USER");
        List<SimpleGrantedAuthority> updatedAuthorities = new ArrayList<>();
        updatedAuthorities.add(authority);
        Authentication authentication = new UsernamePasswordAuthenticationToken(user,null, updatedAuthorities);

        return Mono.just(authentication);
      }
      return Mono.empty();
    } catch (Exception e) {
      // log error here
      return Mono.empty();
    }
  }
}

И, наконец, класс SecurityConfiguration.

@Configuration
@EnableWebFluxSecurity
@RequiredArgsConstructor
public class SecurityConfiguration {

  @Autowired
  private PreAuthenticationConverter preAuthenticationConverter;

  @Autowired
  private OpenIDAuthenticationEntryPoint openIDAuthenticationEntryPoint;

  @Autowired
  private OpenIDReactiveAuthenticationManager openIDReactiveAuthenticationManager;

  SecurityWebFilterChain securityWebFilterChainStg(ServerHttpSecurity http) {
    return http.cors()
        .and()
        .csrf().disable()
        .authorizeExchange()
        .pathMatchers("/actuator/health", "/actuator/info").permitAll()
        .anyExchange().authenticated()
        .and()
        .addFilterAt(preAuthenticationFilter(), SecurityWebFiltersOrder.AUTHENTICATION)
        .exceptionHandling().authenticationEntryPoint(openIDAuthenticationEntryPoint)
        .and()
        .build();
  }

  @Bean
  CorsConfigurationSource corsConfigurationSource() {
    CorsConfiguration configuration = new CorsConfiguration();
    configuration.setAllowedOrigins(Collections.singletonList("*"));
    configuration.addAllowedMethod("GET");
    configuration.addAllowedMethod("POST");
    configuration.addAllowedMethod("DELETE");
    configuration.addAllowedHeader("authorization");
    configuration.addAllowedHeader("content-type");
    UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
    source.registerCorsConfiguration("/**", configuration);
    return source;
  }

  private AuthenticationWebFilter preAuthenticationFilter(){
    AuthenticationWebFilter preAuthenticationFilter = new AuthenticationWebFilter(openIDReactiveAuthenticationManager);
    preAuthenticationFilter.setServerAuthenticationConverter(preAuthenticationConverter);
    return preAuthenticationFilter;
  }
}

Я пробовал различные методы, такие как ручная установка Аутентификации в WebSessionServerSecurityContextRepository, но все же не удалось аутентифицировать пользователя, так как AuthenticationEntryPoint продолжает вызыватьсядля каждого запроса, поступающего от внешнего интерфейса.

ServerSecurityContextRepository serverSecurityContextRepository = new WebSessionServerSecurityContextRepository();
    return serverSecurityContextRepository.save(exchange,
        new SecurityContextImpl(authentication))
        .subscriberContext(ReactiveSecurityContextHolder.withAuthentication(authentication));

Надеясь, что кто-то может дать некоторое представление / руководство о том, почему аутентификация считается не "аутентифицированной" инстобъявление ожидаемого результата, когда пользователь сможет получить доступ к веб-интерфейсу без повторного перенаправления вперед и назад поставщика веб-интерфейса и OpenID с помощью AuthenticationEntryPoint

1 Ответ

0 голосов
/ 25 сентября 2019

Очень трудно понять, что не так, потому что я не могу запустить ваш код, а вы смешиваете императивное программирование с реактивным программированием.

Есть несколько проблем с вашим кодом, на которые я указал в комментарияхниже вашего первоначального вопроса.

Я собираюсь более конкретно объяснить, что не так

public Mono<Void> authRequest(ServerWebExchange serverWebExchange) {

    // Here we are in the imperative world and everything is fine, we get some 
    // stuff and set some parameters.
    System.out.println("AUTH-REQUEST");
    String returnToUrl = "..."; 
    List discoveries = manager.discover( ... );
    DiscoveryInformation discovered = manager.associate(discoveries);

    // Here we now jump into the reactive world, and we start working with Monos. 
    // This means that we have to start chaining things, because we are going to 
    // declare what we want our service to do when we eventually get data in our 
    // Mono.
    return serverWebExchange.getSession()
        .map(session -> {

            AuthRequest authReq = manager.authenticate(discovered, returnToUrl);
            serverWebExchange.getResponse()
                .setStatusCode(HttpStatus.TEMPORARY_REDIRECT);
            serverWebExchange.getResponse()
                .getHeaders()
                .setLocation(URI.create(authReq.getDestinationUrl(true)));      

            session.getAttributes().put("openid-disc", discovered);
        return serverWebExchange.getResponse().setComplete();
    })
}

Надеюсь, вы поймете концепцию более четко с этим примером.

...