Skip to content

Commit 3cfd738

Browse files
committed
Polish
1 parent 38142b9 commit 3cfd738

File tree

4 files changed

+30
-106
lines changed

4 files changed

+30
-106
lines changed

api/src/main/java/io/kafbat/ui/config/auth/AbstractAuthSecurityConfig.java

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,24 +6,29 @@ protected AbstractAuthSecurityConfig() {
66

77
}
88

9+
public static final String INDEX_HTML = "/static/index.html";
10+
911
protected static final String[] AUTH_WHITELIST = {
10-
"/css/**",
11-
"/js/**",
12-
"/media/**",
12+
/* STATIC */
13+
"/index.html",
14+
"/assets/**",
15+
"/manifest.json",
16+
"/favicon.svg",
17+
"/favicon/**",
18+
19+
"/static/**",
1320
"/resources/**",
21+
22+
/* ACTUATOR */
1423
"/actuator/health/**",
1524
"/actuator/info",
1625
"/actuator/prometheus",
17-
"/auth",
26+
27+
/* AUTH */
1828
"/login",
1929
"/logout",
2030
"/oauth2/**",
21-
"/static/**",
2231
"/api/config/authentication",
23-
"/index.html",
24-
"/assets/**",
25-
"/manifest.json",
26-
"/favicon/**",
2732
"/api/authorization"
2833
};
2934

api/src/main/java/io/kafbat/ui/config/auth/OAuthSecurityConfig.java

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ public class OAuthSecurityConfig extends AbstractAuthSecurityConfig {
5353
public SecurityWebFilterChain configure(ServerHttpSecurity http, OAuthLogoutSuccessHandler logoutHandler) {
5454
log.info("Configuring OAUTH2 authentication.");
5555

56-
ServerHttpSecurity builder = http.authorizeExchange(spec -> spec
56+
var builder = http.authorizeExchange(spec -> spec
5757
.pathMatchers(AUTH_WHITELIST)
5858
.permitAll()
5959
.anyExchange()
@@ -64,9 +64,8 @@ public SecurityWebFilterChain configure(ServerHttpSecurity http, OAuthLogoutSucc
6464
.csrf(ServerHttpSecurity.CsrfSpec::disable);
6565

6666

67-
builder.addFilterAt(new StaticFileWebFilter(
68-
"/login", new ClassPathResource("/static/index.html")
69-
), SecurityWebFiltersOrder.LOGIN_PAGE_GENERATING);
67+
builder.addFilterAt(new StaticFileWebFilter("/login", new ClassPathResource(INDEX_HTML)),
68+
SecurityWebFiltersOrder.LOGIN_PAGE_GENERATING);
7069

7170
return builder.build();
7271
}
Lines changed: 4 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -1,105 +1,22 @@
11
package io.kafbat.ui.controller;
22

3-
import java.nio.charset.Charset;
43
import lombok.RequiredArgsConstructor;
54
import lombok.extern.slf4j.Slf4j;
65
import org.springframework.core.io.ClassPathResource;
7-
import org.springframework.security.web.server.csrf.CsrfToken;
8-
import org.springframework.util.MultiValueMap;
96
import org.springframework.web.bind.annotation.GetMapping;
107
import org.springframework.web.bind.annotation.RestController;
11-
import org.springframework.web.server.ServerWebExchange;
128
import reactor.core.publisher.Mono;
139

1410
@RestController
1511
@RequiredArgsConstructor
1612
@Slf4j
1713
public class AuthenticationController {
1814

19-
@GetMapping(value = "/login", produces = {"text/html"})
20-
public Mono<ClassPathResource> getLoginPage(ServerWebExchange exchange) {
21-
return Mono.just(new ClassPathResource("static/index.html"));
22-
}
23-
24-
@GetMapping(value = "/auth", produces = {"text/html"})
25-
public Mono<byte[]> getAuth(ServerWebExchange exchange) {
26-
Mono<CsrfToken> token = exchange.getAttributeOrDefault(CsrfToken.class.getName(), Mono.empty());
27-
return token
28-
.map(AuthenticationController::csrfToken)
29-
.defaultIfEmpty("")
30-
.map(csrfTokenHtmlInput -> createPage(exchange, csrfTokenHtmlInput));
31-
}
32-
33-
private byte[] createPage(ServerWebExchange exchange, String csrfTokenHtmlInput) {
34-
MultiValueMap<String, String> queryParams = exchange.getRequest()
35-
.getQueryParams();
36-
String contextPath = exchange.getRequest().getPath().contextPath().value();
37-
String page =
38-
"<!DOCTYPE html>\n" + "<html lang=\"en\">\n" + " <head>\n"
39-
+ " <meta charset=\"utf-8\">\n"
40-
+ " <meta name=\"viewport\" content=\"width=device-width, initial-scale=1, "
41-
+ "shrink-to-fit=no\">\n"
42-
+ " <meta name=\"description\" content=\"\">\n"
43-
+ " <meta name=\"author\" content=\"\">\n"
44-
+ " <title>Please sign in</title>\n"
45-
+ " <link href=\"" + contextPath + "/static/css/bootstrap.min.css\" rel=\"stylesheet\" "
46-
+ "integrity=\"sha384-/Y6pD6FV/Vv2HJnA6t+vslU6fwYXjCFtcEpHbNJ0lyAFsXTsjBbfaDjzALeQsN6M\" "
47-
+ "crossorigin=\"anonymous\">\n"
48-
+ " <link href=\"" + contextPath + "/static/css/signin.css\" "
49-
+ "rel=\"stylesheet\" crossorigin=\"anonymous\"/>\n"
50-
+ " </head>\n"
51-
+ " <body>\n"
52-
+ " <div class=\"container\">\n"
53-
+ formLogin(queryParams, contextPath, csrfTokenHtmlInput)
54-
+ " </div>\n"
55-
+ " </body>\n"
56-
+ "</html>";
57-
58-
return page.getBytes(Charset.defaultCharset());
59-
}
15+
private static final String INDEX_HTML = "/static/index.html";
6016

61-
private String formLogin(
62-
MultiValueMap<String, String> queryParams,
63-
String contextPath, String csrfTokenHtmlInput) {
64-
65-
boolean isError = queryParams.containsKey("error");
66-
boolean isLogoutSuccess = queryParams.containsKey("logout");
67-
return
68-
" <form class=\"form-signin\" method=\"post\" action=\"" + contextPath + "/auth\">\n"
69-
+ " <h2 class=\"form-signin-heading\">Please sign in</h2>\n"
70-
+ createError(isError)
71-
+ createLogoutSuccess(isLogoutSuccess)
72-
+ " <p>\n"
73-
+ " <label for=\"username\" class=\"sr-only\">Username</label>\n"
74-
+ " <input type=\"text\" id=\"username\" name=\"username\" class=\"form-control\" "
75-
+ "placeholder=\"Username\" required autofocus>\n"
76-
+ " </p>\n" + " <p>\n"
77-
+ " <label for=\"password\" class=\"sr-only\">Password</label>\n"
78-
+ " <input type=\"password\" id=\"password\" name=\"password\" "
79-
+ "class=\"form-control\" placeholder=\"Password\" required>\n"
80-
+ " </p>\n" + csrfTokenHtmlInput
81-
+ " <button class=\"btn btn-lg btn-primary btn-block\" "
82-
+ "type=\"submit\">Sign in</button>\n"
83-
+ " </form>\n";
84-
}
85-
86-
private static String csrfToken(CsrfToken token) {
87-
return " <input type=\"hidden\" name=\""
88-
+ token.getParameterName()
89-
+ "\" value=\""
90-
+ token.getToken()
91-
+ "\">\n";
92-
}
93-
94-
private static String createError(boolean isError) {
95-
return isError
96-
? "<div class=\"alert alert-danger\" role=\"alert\">Invalid credentials</div>"
97-
: "";
17+
@GetMapping(value = "/login", produces = {"text/html"})
18+
public Mono<ClassPathResource> getLoginPage() {
19+
return Mono.just(new ClassPathResource(INDEX_HTML));
9820
}
9921

100-
private static String createLogoutSuccess(boolean isLogoutSuccess) {
101-
return isLogoutSuccess
102-
? "<div class=\"alert alert-success\" role=\"alert\">You have been signed out</div>"
103-
: "";
104-
}
10522
}

api/src/main/java/io/kafbat/ui/util/StaticFileWebFilter.java

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
package io.kafbat.ui.util;
22

33
import java.io.IOException;
4-
import java.io.InputStream;
4+
import org.jetbrains.annotations.NotNull;
55
import org.springframework.core.io.ClassPathResource;
66
import org.springframework.core.io.buffer.DataBufferFactory;
77
import org.springframework.http.HttpMethod;
@@ -16,20 +16,22 @@
1616
import reactor.core.publisher.Mono;
1717

1818
public class StaticFileWebFilter implements WebFilter {
19-
private ServerWebExchangeMatcher matcher;
20-
private String contents;
19+
20+
private final ServerWebExchangeMatcher matcher;
21+
private final String contents;
2122

2223
public StaticFileWebFilter(String path, ClassPathResource resource) {
2324
this.matcher = ServerWebExchangeMatchers.pathMatchers(HttpMethod.GET, path);
24-
try (InputStream inputStream = resource.getInputStream()) {
25-
this.contents = ResourceUtil.readAsString(resource);
25+
26+
try {
27+
this.contents = ResourceUtil.readAsString(resource);
2628
} catch (IOException e) {
2729
throw new RuntimeException(e);
2830
}
2931
}
3032

3133
@Override
32-
public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
34+
public @NotNull Mono<Void> filter(@NotNull ServerWebExchange exchange, WebFilterChain chain) {
3335
return this.matcher.matches(exchange)
3436
.filter(ServerWebExchangeMatcher.MatchResult::isMatch)
3537
.switchIfEmpty(chain.filter(exchange).then(Mono.empty()))
@@ -38,6 +40,7 @@ public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
3840

3941
private Mono<Void> render(ServerWebExchange exchange) {
4042
String contextPath = exchange.getRequest().getPath().contextPath().value();
43+
4144
String contentBody = contents
4245
.replace("\"assets/", "\"" + contextPath + "/assets/")
4346
.replace("PUBLIC-PATH-VARIABLE", contextPath);

0 commit comments

Comments
 (0)