Skip to content

Commit 1a9d45a

Browse files
NFC-47 Remove state logic from example
1 parent 70769a9 commit 1a9d45a

File tree

5 files changed

+44
-90
lines changed

5 files changed

+44
-90
lines changed

example/src/main/java/eu/webeid/example/config/ApplicationConfiguration.java

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@
2626
import eu.webeid.example.security.WebEidAjaxLoginProcessingFilter;
2727
import eu.webeid.example.security.WebEidChallengeNonceFilter;
2828
import eu.webeid.example.security.WebEidMobileAuthInitFilter;
29-
import eu.webeid.example.security.state.MobileAuthStateStore;
3029
import eu.webeid.example.security.ui.WebEidLoginPageGeneratingFilter;
3130
import eu.webeid.security.challenge.ChallengeNonceGenerator;
3231
import eu.webeid.security.challenge.ChallengeNonceStore;
@@ -53,7 +52,7 @@
5352
public class ApplicationConfiguration implements WebMvcConfigurer {
5453

5554
@Bean
56-
public SecurityFilterChain filterChain(HttpSecurity http, AuthTokenDTOAuthenticationProvider authTokenDTOAuthenticationProvider, AuthenticationConfiguration authConfig, ChallengeNonceGenerator challengeNonceGenerator, ChallengeNonceStore challengeNonceStore, MobileAuthStateStore mobileAuthStateStore) throws Exception {
55+
public SecurityFilterChain filterChain(HttpSecurity http, AuthTokenDTOAuthenticationProvider authTokenDTOAuthenticationProvider, AuthenticationConfiguration authConfig, ChallengeNonceGenerator challengeNonceGenerator, ChallengeNonceStore challengeNonceStore) throws Exception {
5756

5857
var filter = new WebEidAjaxLoginProcessingFilter("/auth/login", authConfig.getAuthenticationManager());
5958

@@ -69,24 +68,18 @@ public SecurityFilterChain filterChain(HttpSecurity http, AuthTokenDTOAuthentica
6968
.anyRequest().permitAll()
7069
)
7170
.authenticationProvider(authTokenDTOAuthenticationProvider)
72-
.addFilterBefore(new WebEidLoginPageGeneratingFilter(mobileAuthStateStore, challengeNonceStore), UsernamePasswordAuthenticationFilter.class)
71+
.addFilterBefore(new WebEidLoginPageGeneratingFilter(), UsernamePasswordAuthenticationFilter.class)
7372
.addFilterBefore(new WebEidChallengeNonceFilter(challengeNonceGenerator), AuthorizationFilter.class)
74-
.addFilterAfter(new WebEidMobileAuthInitFilter(challengeNonceGenerator, mobileAuthStateStore), CsrfFilter.class)
73+
.addFilterAfter(new WebEidMobileAuthInitFilter(challengeNonceGenerator, challengeNonceStore), CsrfFilter.class)
7574
.addFilterBefore(filter, UsernamePasswordAuthenticationFilter.class)
7675
.headers(h -> h.frameOptions(HeadersConfigurer.FrameOptionsConfig::sameOrigin))
7776
.logout(l -> l.logoutSuccessHandler(new HttpStatusReturningLogoutSuccessHandler()))
7877
.build();
7978
}
8079

81-
@Bean
82-
public MobileAuthStateStore mobileAuthStateStore() {
83-
return new MobileAuthStateStore(5 * 60L);
84-
}
85-
8680
@Override
8781
public void addViewControllers(ViewControllerRegistry registry) {
8882
registry.addViewController("/").setViewName("index");
8983
registry.addViewController("/welcome").setViewName("welcome");
9084
}
91-
9285
}

example/src/main/java/eu/webeid/example/config/SameSiteCookieConfiguration.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ public class SameSiteCookieConfiguration implements WebMvcConfigurer {
3535
public TomcatContextCustomizer configureSameSiteCookies() {
3636
return context -> {
3737
final Rfc6265CookieProcessor cookieProcessor = new Rfc6265CookieProcessor();
38-
cookieProcessor.setSameSiteCookies("strict");
38+
cookieProcessor.setSameSiteCookies("lax");
3939
context.setCookieProcessor(cookieProcessor);
4040
};
4141
}

example/src/main/java/eu/webeid/example/security/WebEidMobileAuthInitFilter.java

Lines changed: 13 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,13 @@
11
package eu.webeid.example.security;
22

33
import com.fasterxml.jackson.databind.ObjectMapper;
4-
import eu.webeid.example.security.state.MobileAuthStateStore;
54
import eu.webeid.example.service.dto.MobileAuthInitResponse;
65
import eu.webeid.security.challenge.ChallengeNonceGenerator;
6+
import eu.webeid.security.challenge.ChallengeNonceStore;
77
import jakarta.servlet.FilterChain;
88
import jakarta.servlet.ServletException;
99
import jakarta.servlet.http.HttpServletRequest;
1010
import jakarta.servlet.http.HttpServletResponse;
11-
import org.slf4j.Logger;
12-
import org.slf4j.LoggerFactory;
1311
import org.springframework.http.HttpMethod;
1412
import org.springframework.lang.NonNull;
1513
import org.springframework.security.web.servlet.util.matcher.PathPatternRequestMatcher;
@@ -23,45 +21,43 @@
2321
import java.util.Map;
2422

2523
public final class WebEidMobileAuthInitFilter extends OncePerRequestFilter {
26-
private static final Logger LOG = LoggerFactory.getLogger(WebEidMobileAuthInitFilter.class);
2724
private static final ObjectMapper MAPPER = new ObjectMapper();
2825
private final RequestMatcher matcher =
2926
PathPatternRequestMatcher.withDefaults().matcher(HttpMethod.POST, "/auth/mobile/auth/init");
3027

3128
private final ChallengeNonceGenerator nonceGenerator;
32-
private final MobileAuthStateStore stateStore;
29+
private final ChallengeNonceStore challengeNonceStore;
3330

34-
public WebEidMobileAuthInitFilter(ChallengeNonceGenerator nonceGenerator, MobileAuthStateStore stateStore) {
31+
public WebEidMobileAuthInitFilter(ChallengeNonceGenerator nonceGenerator,
32+
ChallengeNonceStore challengeNonceStore) {
3533
this.nonceGenerator = nonceGenerator;
36-
this.stateStore = stateStore;
34+
this.challengeNonceStore = challengeNonceStore;
3735
}
3836

3937
@Override
4038
protected void doFilterInternal(@NonNull HttpServletRequest request,
4139
@NonNull HttpServletResponse response,
42-
@NonNull FilterChain chain) throws ServletException, IOException {
43-
if (!matcher.matches(request)) { chain.doFilter(request, response); return; }
40+
@NonNull FilterChain chain) throws IOException, ServletException {
41+
if (!matcher.matches(request)) {
42+
chain.doFilter(request, response);
43+
return;
44+
}
4445

4546
var challenge = nonceGenerator.generateAndStoreNonce();
46-
String state = stateStore.put(challenge);
47+
challengeNonceStore.put(challenge);
4748

4849
String loginUri = ServletUriComponentsBuilder.fromCurrentContextPath()
49-
.path("/auth/eid/login").queryParam("state", state).build().toUriString();
50+
.path("/auth/eid/login").build().toUriString();
5051

5152
String payloadJson = MAPPER.writeValueAsString(Map.of(
5253
"challenge", challenge.getBase64EncodedNonce(),
53-
"login_uri", loginUri,
54-
"state", state
54+
"login_uri", loginUri
5555
));
5656
String encoded = Base64.getEncoder().encodeToString(payloadJson.getBytes(StandardCharsets.UTF_8));
5757
String eidAuthUri = "web-eid-mobile://auth#" + encoded;
5858

5959
response.setContentType("application/json");
6060
MAPPER.writeValue(response.getWriter(), new MobileAuthInitResponse(eidAuthUri));
61-
62-
var session = request.getSession(false);
63-
var sid = (session != null ? session.getId() : "null");
64-
LOG.info("MOBILE INIT: sessionId={}, issuing nonce, state={}", sid, state);
6561
}
6662

6763
@Override

example/src/main/java/eu/webeid/example/security/state/MobileAuthStateStore.java

Lines changed: 0 additions & 35 deletions
This file was deleted.

example/src/main/java/eu/webeid/example/security/ui/WebEidLoginPageGeneratingFilter.java

Lines changed: 27 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
package eu.webeid.example.security.ui;
22

3-
import eu.webeid.example.security.state.MobileAuthStateStore;
4-
import eu.webeid.security.challenge.ChallengeNonceStore;
53
import jakarta.servlet.FilterChain;
64
import jakarta.servlet.ServletException;
75
import jakarta.servlet.http.HttpServletRequest;
@@ -10,6 +8,7 @@
108
import org.slf4j.LoggerFactory;
119
import org.springframework.http.HttpMethod;
1210
import org.springframework.lang.NonNull;
11+
import org.springframework.security.web.csrf.CsrfToken;
1312
import org.springframework.security.web.servlet.util.matcher.PathPatternRequestMatcher;
1413
import org.springframework.security.web.util.matcher.RequestMatcher;
1514
import org.springframework.web.filter.OncePerRequestFilter;
@@ -19,8 +18,6 @@
1918
public final class WebEidLoginPageGeneratingFilter extends OncePerRequestFilter {
2019
private static final Logger LOG = LoggerFactory.getLogger(WebEidLoginPageGeneratingFilter.class);
2120
private final RequestMatcher requestMatcher = PathPatternRequestMatcher.withDefaults().matcher(HttpMethod.GET, "/auth/eid/login");
22-
private final MobileAuthStateStore stateStore;
23-
private final ChallengeNonceStore challengeNonceStore;
2421
private static final String LOGIN_PAGE_HTML = """
2522
<!doctype html>
2623
<html lang="en">
@@ -38,7 +35,9 @@ public final class WebEidLoginPageGeneratingFilter extends OncePerRequestFilter
3835
3936
let payload;
4037
try { payload = JSON.parse(atob(frag)); } catch (e) {
41-
location.replace("/?mobileAuthError=bad_payload"); return;
38+
console.error("Failed to parse payload", e);
39+
location.replace("/?mobileAuthError=bad_payload");
40+
return;
4241
}
4342
4443
const csrfToken = document.querySelector('#csrftoken').content;
@@ -48,24 +47,28 @@ public final class WebEidLoginPageGeneratingFilter extends OncePerRequestFilter
4847
4948
fetch("/auth/login", {
5049
method: "POST",
51-
headers: { "Content-Type": "application/json", [csrfHeaderName]: csrfToken },
50+
headers: {
51+
"Content-Type": "application/json",
52+
[csrfHeaderName]: csrfToken
53+
},
5254
body: JSON.stringify({ "auth-token": authToken }),
5355
credentials: "include"
5456
})
55-
.then(r => { if (!r.ok) throw new Error("HTTP " + r.status); location.replace("/welcome"); })
56-
.catch(() => location.replace("/?mobileAuthError=login_failed"));
57+
.then(r => {
58+
if (!r.ok) throw new Error("HTTP " + r.status);
59+
window.location.replace("/welcome");
60+
})
61+
.catch(e => {
62+
console.error("Login failed", e);
63+
window.location.replace("/?mobileAuthError=login_failed");
64+
});
5765
})();
5866
</script>
5967
Signing you in…
6068
</body>
6169
</html>
6270
""";
6371

64-
public WebEidLoginPageGeneratingFilter(MobileAuthStateStore stateStore, ChallengeNonceStore challengeNonceStore) {
65-
this.stateStore = stateStore;
66-
this.challengeNonceStore = challengeNonceStore;
67-
}
68-
6972
@Override
7073
protected void doFilterInternal(@NonNull HttpServletRequest request, @NonNull HttpServletResponse response, @NonNull FilterChain chain)
7174
throws IOException, ServletException {
@@ -74,22 +77,19 @@ protected void doFilterInternal(@NonNull HttpServletRequest request, @NonNull Ht
7477
return;
7578
}
7679

77-
String state = request.getParameter("state");
78-
if (state != null && !state.isBlank()) {
79-
var challenge = stateStore.consume(state);
80-
var session = request.getSession(true);
81-
var sid = (session != null ? session.getId() : "null");
82-
if (challenge != null) {
83-
challengeNonceStore.put(challenge);
84-
LOG.info("LOGIN PAGE: rehydrated challenge via state={}, sessionId={}", state, sid);
85-
} else {
86-
LOG.warn("LOGIN PAGE: state missing/expired: {}, sessionId={}", state, sid);
87-
}
80+
var session = request.getSession(false);
81+
LOG.info("LOGIN PAGE: rendering login page for sessionId={}", session != null ? session.getId() : "null");
82+
83+
var csrf = (CsrfToken) request.getAttribute(CsrfToken.class.getName());
84+
if (csrf == null) {
85+
csrf = (CsrfToken) request.getAttribute("_csrf");
8886
}
8987

90-
var csrf = (org.springframework.security.web.csrf.CsrfToken) request.getAttribute(org.springframework.security.web.csrf.CsrfToken.class.getName());
91-
if (csrf == null) csrf = (org.springframework.security.web.csrf.CsrfToken) request.getAttribute("_csrf");
92-
String html = generateHtml(csrf != null ? csrf.getToken() : "", csrf != null ? csrf.getHeaderName() : "X-CSRF-TOKEN");
88+
String html = generateHtml(
89+
csrf != null ? csrf.getToken() : "",
90+
csrf != null ? csrf.getHeaderName() : "X-CSRF-TOKEN"
91+
);
92+
9393
response.setContentType("text/html;charset=UTF-8");
9494
response.getWriter().write(html);
9595
}

0 commit comments

Comments
 (0)