snap-admin icon indicating copy to clipboard operation
snap-admin copied to clipboard

Question: how to use Keycloak to protect the admin pages ?

Open daaa57150 opened this issue 1 year ago • 3 comments

Hi,

I'm currently testing Snap Admin and I'm a bit stuck with the security. We are using Keycloak as our JWT token provider to secure our endpoints, I'm a bit lost as how I could use that to protect the admin pages.

Has anyone tried that ? Or any other JWT identity provider ?

Thanks!

daaa57150 avatar May 16 '24 21:05 daaa57150

Hi,

I assume that the procedure listed in the Security section of the documentation is not applicable in your case (maybe with some adaptations)?

I've never used JWT so I'm just trying to understand what is different w.r.t "normal" authentication. Can you show what your configuration looks like/where the problem occurs exactly?

aileftech avatar May 20 '24 06:05 aileftech

This is what I currently have as my SecurityFilterChain:

@Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http.authorizeHttpRequests((authz) ->
                authz.requestMatchers(HttpMethod.GET, "/*").permitAll()
                        .anyRequest().authenticated());

        // was using REST only up to now, so STATELESS made sense
        http.sessionManagement(sess -> sess.sessionCreationPolicy(SessionCreationPolicy.STATELESS));
        // Custom conversion from the JWT token to our User/Principal class
        http.oauth2ResourceServer(oauth2 -> oauth2.jwt(jwt -> jwt.jwtAuthenticationConverter(jwtConverter)));

        return http.build();
    }

Since we are all beginners in this part of the project, not sure it's totally correct but for now it works with our rest controllers.

I can probably adapt what's in the in the Security section, but the question is how ;). A login page doesn't make sense as the login is made from outside the app in Keycloak.

I'll see if I can find something, I hoped someone would have done it already.

daaa57150 avatar May 21 '24 08:05 daaa57150

From the code it seems you have permitAll() on every GET request, so If I understand correctly you could try something like this and change the policy for requests that are inside SnapAdmin:

@Autowired
private SnapAdminProperties properties;


@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
       String baseUrl = properties.getBaseUrl(); // <- Get the SnapAdmin base URL

    http.authorizeHttpRequests((authz) ->
            authz
                      // Added these two lines to make requests to the baseURL authenticated instead of permitAll
                    .requestMatchers(AntPathRequestMatcher.antMatcher("/" + baseUrl + "/**"))
                     .authenticated()
                    .requestMatchers(HttpMethod.GET, "/*").permitAll()
                    .anyRequest().authenticated());

    // was using REST only up to now, so STATELESS made sense
    http.sessionManagement(sess -> sess.sessionCreationPolicy(SessionCreationPolicy.STATELESS));
    // Custom conversion from the JWT token to our User/Principal class
    http.oauth2ResourceServer(oauth2 -> oauth2.jwt(jwt -> jwt.jwtAuthenticationConverter(jwtConverter)));

    return http.build();
}

I believe this should work with any authentication method since we're just editing the security filter chain, but I've never tried JWT so let me know if it actually works.

aileftech avatar May 23 '24 06:05 aileftech