javaplayframeworkpac4j

Pacj and Websocket authentication and authorization


@Secure doesn't work for websocket in pac4j-play how do i secure a websocket in java pac4j play thanks this what i don now if (!profilesHelper.getProfilesWithHeader(request).isEmpty()) { UserProfile profile = profilesHelper.getProfilesWithHeader(request).get(0);

        // Check if the user is authorized
        if (profile.getRoles().contains("ROLE_USER")) {
   
                return CompletableFuture.completedFuture(
                        F.Either.Right(createFlowForActor(request)));
          
        }
    }
    return CompletableFuture.completedFuture(F.Either.Left(forbidden()));

how manually you do secure in pac4j without using anotations

filters don't work on websocket end point

Edit:

but i tried this method

private CompletionStage<F.Either<Result, Flow<JsonNode, JsonNode, ?>>>
createActorFlow(Http.RequestHeader request) {

        final String clients = "CustomFormClient, FacebookClient, TwitterClient, Google2Client, CustomFormClientRegister";
        final String authorizers = "USER";
        final String matchers = "+csrfToken";
       


                return (CompletionStage<F.Either<Result, Flow<JsonNode, JsonNode, ?>>>)
                        config.getSecurityLogic().perform(config, (webCtx, session, profiles) -> {
                                return CompletableFuture.completedFuture(
                                        F.Either.Right(createFlowForActor(request)));
                        },clients,authorizers,matchers, new PlayFrameworkParameters(request));


}

private Flow<JsonNode, JsonNode, ?> createFlowForActor(Http.RequestHeader requestHeader) {
    return ActorFlow.actorRef(out -> MFAWebsocketActor.props(
                    out, requestHeader, userRepository, mailerClient, profilesHelper, materializer),
            actorSystem, materializer);
}

this works but only if user is authenticated and authorized but if user don't get authenticated or authorized, it returns a forbiden result which ends up in this error

2024-06-20 20:30:56 ERROR o.apache.pekko.actor.ActorSystemImpl org.apache.pekko.actor.ActorSystemImpl(play-dev-mode) Internal server error, sending 500 response java.lang.ClassCastException: play.mvc.Result incompatible with java.util.concurrent.CompletionStage



Solution

  • It solved if user don't get authenticated or authorized, it returns a forbiden result which ends up in this error because return type of createActorFlow

    now this way it works

    public WebSocket mfaSocket() {
        return WebSocket.Json
                .acceptOrResult(request -> {
                    final String clients = "CustomFormClient, FacebookClient, TwitterClient, Google2Client, CustomFormClientRegister";
                    final String authorizers = "USER_UNVERIFIED";
                    final String matchers = "+csrfToken";
                    // Check if the user is authorized
    
    
                    Object result =
                            config.getSecurityLogic().perform(config, (webCtx, session, profiles) -> {
                                return CompletableFuture.completedFuture(
                                        F.Either.Right(createFlowForActor(request)));
    
                            },clients,authorizers,matchers, new PlayFrameworkParameters(request));
    
                    if(result instanceof Result){
                        if(((Result)result).status() != 200){
                            return CompletableFuture.completedFuture(F.Either.Left((Result)result));
                        }
    
                    }
                    return (CompletionStage<F.Either<Result, Flow<JsonNode, JsonNode, ?>>>) result;
                });
    }