Custom authentication filter

Hello, i want to create a custom authentication without using the login form. It is a passwordless auth that realys on an external service, kind of sso. I’ve created a custom filter and everything seems to work properly, except that after authenticating Vaadin routes annotated with @PermitAll still don’t allow me the access. This is my security config

@Configuration
@EnableWebSecurity
@RequiredArgsConstructor
public class SecurityConfig extends VaadinWebSecurity {

private final JwtUtils jwtUtils;
private final AuthenticationConfiguration authenticationConfiguration;

@Bean
public Web3AuthenticationFilter web3AuthenticationFilter() throws Exception {
    AuthenticationManager authenticationManager = authenticationConfiguration.getAuthenticationManager();
    Web3AuthenticationFilter authenticationFilter = new Web3AuthenticationFilter(authenticationManager, jwtUtils);
    authenticationFilter.setAuthenticationManager(authenticationManager);
    authenticationFilter.setAuthenticationFailureHandler(new SimpleUrlAuthenticationFailureHandler("/login?error"));

    return authenticationFilter;
}

@Override
protected void configure(WebSecurity web) throws Exception {
    web.ignoring().requestMatchers("/", "/login");
}

@Override
protected void configure(HttpSecurity http) throws Exception {
    http.addFilterBefore(web3AuthenticationFilter(), UsernamePasswordAuthenticationFilter.class);
    super.configure(http);
}

}

The /login path just triggers my custom filter

Thanks for the help

It seems to me that vaadin doesn’t start a new session neither reads the default spring security cookie. Inside the filter I’ve added
VaadinSavedRequestAwareAuthenticationSuccessHandler as success handler, but with no results

Hi, I was struggling with this issue for long, as some others.

we need someone from the vaadin team to help, if they will

It is mandatory feature this days, where IDM changes all the time

Yes, plus it’s working fine in a normal spring boot app, it should be that easy also in vaadin. At least I’m not the only one having this issue :smiling_face_with_tear:

If you want attention, a reproduce able example and a GitHub issue showcasing the problem, would probably help the flow team to identify or debug the case :wink:

I will try to set something up , thanks

Well, after investigating and going at low level, i understood how this can be done.

What i wanted to achieve was to be able to login without passing from a separate login view, but just by calling an external js service returning a jwt. I ended up doing this:

Button loginButton = new Button(“Login”, e →
UI.getCurrent().getPage().executeJs(“return login();”)
.then(res → {
JSONObject jsonResponse = new JSONObject(res.toJson());
Map<String, Object> claims = jwtUtils.parseToken(jsonResponse.getString(“idToken”).trim());
AuthenticatedUser user = new AuthenticatedUser(claims.get(“email”).toString(), “”, Collections.emptyList());

                        var authentication = new UsernamePasswordAuthenticationToken(user, null, user.getAuthorities());
                        SecurityContextHolder.getContext().setAuthentication(authenticationManager.authenticate(authentication));
                        SecurityContext securityContext = SecurityContextHolder.getContext();
                        securityContext.setAuthentication(authentication);
                        VaadinSession.getCurrent().getSession().setAttribute("SPRING_SECURITY_CONTEXT", securityContext);
                        log.info("Logged in as: {}", SecurityContextHolder.getContext().getAuthentication().getName());
                    }));

The trick is here: VaadinSession.getCurrent().getSession().setAttribute(“SPRING_SECURITY_CONTEXT”, securityContext);

After this, the user is fully logged in, and the protetected routes are also accessible. The next requests maintain the authentication.

To logout, just call VaadinSession.getCurrent().getSession().invalidate();