Repository: provectus/kafka-ui
Issue: Authentication mechanism with simple Username and password 
Labels: type/enhancement

Hi Team, Is there any simple authentication mechanism for the kafka-ui by default. I see we have SSL and SSO option, but without those things it would be better to have simple user and password for login to dashboard in terms of Security concerns

Issue comments:
Hi, @vangahari . Thanks for creating this issue. This feature looks interesting we'll try to add it in next versions
Hi, @germanosin. Thanks for the reply.
It would be grateful if we can have this feature in the next versions. 
This is already supported by spring and env variables:

```
AUTH_ENABLED=true
SPRING_SECURITY_USER_NAME=admin
SPRING_SECURITY_USER_PASSWORD=pass
```

But broken dues to the `CSRF` not configured properly: https://github.com/provectus/kafka-ui/issues/287#issuecomment-903986233

I have not tried SSO, but I presume this should be broken with SSO as well as `CSRF` token is not passed to the API and enabled by default.
@apryiomka Yes, Got the same issue. I configured as you mentioned above, got the same issue when creating topic from the dashboard.


Pull request review comments:

Patch that resolved the issue:
diff --git a/kafka-ui-api/src/main/java/com/provectus/kafka/ui/config/OAuthSecurityConfig.java b/kafka-ui-api/src/main/java/com/provectus/kafka/ui/config/OAuthSecurityConfig.java
index f28e96ed82f..3e8bcd478f2 100644
--- a/kafka-ui-api/src/main/java/com/provectus/kafka/ui/config/OAuthSecurityConfig.java
+++ b/kafka-ui-api/src/main/java/com/provectus/kafka/ui/config/OAuthSecurityConfig.java
@@ -1,17 +1,29 @@
 package com.provectus.kafka.ui.config;
 
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.context.ApplicationContext;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
 import org.springframework.security.config.annotation.web.reactive.EnableWebFluxSecurity;
 import org.springframework.security.config.web.server.ServerHttpSecurity;
 import org.springframework.security.web.server.SecurityWebFilterChain;
+import org.springframework.util.ClassUtils;
 
 @Configuration
 @EnableWebFluxSecurity
 @ConditionalOnProperty(value = "auth.enabled", havingValue = "true")
 public class OAuthSecurityConfig {
 
+  public static final String REACTIVE_CLIENT_REGISTRATION_REPOSITORY_CLASSNAME =
+      "org.springframework.security.oauth2.client.registration."
+          + "ReactiveClientRegistrationRepository";
+
+  private static final boolean isOAuth2Present = ClassUtils.isPresent(
+      REACTIVE_CLIENT_REGISTRATION_REPOSITORY_CLASSNAME,
+      OAuthSecurityConfig.class.getClassLoader()
+  );
+
   private static final String[] AUTH_WHITELIST = {
       "/css/**",
       "/js/**",
@@ -24,17 +36,43 @@ public class OAuthSecurityConfig {
       "/oauth2/**"
   };
 
+  @Autowired
+  ApplicationContext context;
+
   @Bean
   public SecurityWebFilterChain configure(ServerHttpSecurity http) {
-    return http.authorizeExchange()
+    http.authorizeExchange()
         .pathMatchers(AUTH_WHITELIST).permitAll()
-        .anyExchange().authenticated()
-        .and()
-        .oauth2Login()
-        .and()
-        .csrf().disable()
-        .build();
+        .anyExchange()
+        .authenticated();
+
+    if (isOAuth2Present && OAuth2ClasspathGuard.shouldConfigure(this.context)) {
+      OAuth2ClasspathGuard.configure(this.context, http);
+    } else {
+      http
+          .httpBasic().and()
+          .formLogin();
+    }
+
+    SecurityWebFilterChain result = http.csrf().disable().build();
+    return result;
   }
 
+  private static class OAuth2ClasspathGuard {
+    static void configure(ApplicationContext context, ServerHttpSecurity http) {
+      http
+          .oauth2Login().and()
+          .oauth2Client();
+    }
+
+    static boolean shouldConfigure(ApplicationContext context) {
+      ClassLoader loader = context.getClassLoader();
+      Class<?> reactiveClientRegistrationRepositoryClass =
+          ClassUtils.resolveClassName(REACTIVE_CLIENT_REGISTRATION_REPOSITORY_CLASSNAME, loader);
+      return context.getBeanNamesForType(reactiveClientRegistrationRepositoryClass).length == 1;
+    }
+  }
+
+
 }
 


Test patch: