Multiple security with Hilla preimplemented security

Hi everyone, I want to implement dual security like one is already implemented the Hilla framework and another one we want to implement the Spring Security with JWT authentication. So please if you can help to configure the both securities.

I tried the implement the same without interfering the Hilla configuration but after that we are not able to login into the Hilla application.

Hi @nifty-rat. Could you please briefly describe what you want to achieve? When you say JWT authentication, do you mean the OAuth authentication protocol? If so, what flow or grant type do you want to implement and what other systems are involved?

hi @kismet-alpaca thanks for you quick response.

Below is the security configuration extending Vaadin web security.

———————————————————————————————————————————————————————
@EnableWebSecurity(debug = true)
@Configuration
@Slf4j
public class SecurityConfiguration extends VaadinWebSecurity {

@Value(“${com.test.secret}")
private String authSecret;
@Value("${login.expiryTime}")
private Long expiryTime;

@Bean
public PasswordEncoder passwordEncoder() {
    return new BCryptPasswordEncoder();
}

@Order(1)
@Override
protected void configure(HttpSecurity http) throws Exception {
    http.authorizeHttpRequests(
            authorize -> authorize.requestMatchers(new AntPathRequestMatcher("/images/*.png")).permitAll()
                    .requestMatchers(new AntPathRequestMatcher("/api/generateToken")).permitAll()
                    .requestMatchers(new AntPathRequestMatcher("/api/sample")).permitAll()
    .requestMatchers(new AntPathRequestMatcher(“/test/ping”)).permitAll()
    )
    .csrf((csrf) -> csrf.ignoringRequestMatchers(new AntPathRequestMatcher("/api/**/*")));

    super.configure(http);

    http.sessionManagement(customizer -> customizer.sessionCreationPolicy(SessionCreationPolicy.STATELESS));
    setLoginView(http, "/login");
    setStatelessAuthentication(http, new SecretKeySpec(Base64.getDecoder().decode(authSecret), JwsAlgorithms.HS256),”com.test”);
}

}
——————————————————————————————————————————————————

Using @endpoint we defined api. As per configuration… “/login” api is granted without any security, and permitting other urls.

Now my requirement is to access few apis without vaadin and only JWT authentication.

Hi @nifty-rat. Thanks for the additional explanation. Just to make sure, we are talking about the same things: Like every Hilla app, your Hilla app has a frontend and a corresponding backend (following the backend-for-frontend pattern). The communication between the Hilla frontend and the corresponding backend is protected using stateless authentication, as it is described here: Stateless Authentication | Security | Guides | React | Hilla Docs. Is that correct? In addition to that, you are now introducing an additional backend/api, which is available under the “/api” path and that should use another form of JWT authentication. Is that correct? Who is the desired consumer of this additional backend/api?

@kismet-alpaca Yes you are correct, we have additional backend/api. Which is available under the “/api” path and that should be accessible by JWT authentication. these API will be used by mobile app.

Hi @nifty-rat. Thanks for clarification. I do understand that it sounds promising to serve an additional consumer (in your case, a mobile app) using endpoints in a Hilla backend, but I think, that this is something Hilla is not intended to do. If you want to support your mobile app from the same backend as your Hilla frontend, you should define the necessary endpoints separately (using e.g., @RestController) from the communication layer for the Hilla frontend. I can highly recommend this blog post of @original-uguisu to get a better understanding of Hilla’s architecture.

@kismet-alpaca Perhaps you misunderstood. The requirement is to have Hilla @BrowserCallable endpoints that serve the Hilla/React frontend coexist with separate @RestControllers that serve conventional Rest clients written in native code (not browsers). The issue we’re facing is figuring out how to get the stateless auth that Hilla uses to coexist or support authorizing our Rest api. PS I’m working with @nifty-rat on this project. I’m pretty sure we are not the only ones facing this situation. Any assistance would be appreciated, or if there’s someone willing to take this bit on as a paid project, please reach out.

You can always contact Vaadin about help as well. They are probably the best about integrating anything with Vaadin / Hilla

Hi @visionary-wombat. Maybe I misunderstood :wink: Do you want to maintain the endpoints (annotated with @RestController) for your mobile app in the same backend/project like the endpoints (annotated with @BrowserCallable) for the Hilla frontend? This is something you would probably not do, if you follow the BFF (backend for frontend) pattern: Sam Newman - Backends For Frontends. Any thoughts on this @secure-leopard or @486252265393618966?

Hi @kismet-alpaca @quirky-zebra @secure-leopard @486252265393618966 , we want use the @RestController along with @Endpoint in two separate file. So that Hilla’s endpoints will work for the React UI but as we are using same database for other teams also so we want to use the same backend code for them also.

Now Hilla endpoints are secured by Hilla security.
but now we want to secure @RestController’s APIs using Spring Security using JWT authentication only.

I know Hilla does not intend to use RestApis but still, we want to do it this way.

You can do that, nobody is against that - separation of concerns tho. So create another security filter chain for your API endpoint with your dedicated security rules

Yeah, I did the same but after that we are facing the Login issue to the Hilla UI.
any suggestion on this?

this is the code
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {

    log.info("Entering SecurityConfiguration::securityFilterChain");

    return http
            .csrf(csrf -> csrf.disable())
            .authorizeHttpRequests(auth -> auth
                    .requestMatchers(new AntPathRequestMatcher("/", "GET")).permitAll()
                    .requestMatchers(new AntPathRequestMatcher("/VAADIN/**", "GET")).permitAll()
                    .requestMatchers(new AntPathRequestMatcher("/favicon.ico/**", "GET")).permitAll()
                    .requestMatchers(new AntPathRequestMatcher("/login/**")).permitAll()
                    .requestMatchers(new AntPathRequestMatcher("/connect/**")).permitAll()
                    .requestMatchers(new AntPathRequestMatcher("/api/generateToken")).permitAll()
                    .requestMatchers(new AntPathRequestMatcher("/api/sample")).permitAll()
                    .anyRequest().authenticated()
                    )
            .sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
            // .exceptionHandling(ex -> ex.authenticationEntryPoint(point))
            .authenticationProvider(authenticationProvider())
            .addFilterBefore(jwtAuthFilter, UsernamePasswordAuthenticationFilter.class)
            .build();
}

You write dedicated configs for different things. Now you are mixing Hilla and Rest.

See https://docs.spring.io/spring-security/reference/servlet/architecture.html#servlet-securityfilterchain

Okay, thanks @quirky-zebra