Skip to content

Commit 282bc12

Browse files
aarmamSanderKondratjevNortal
authored andcommitted
NFC-47 Authentication flow fixes and updates
Signed-off-by: Sander Kondratjev [email protected]
1 parent d69817d commit 282bc12

File tree

2 files changed

+67
-38
lines changed

2 files changed

+67
-38
lines changed

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

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,12 +41,14 @@
4141
import org.springframework.security.web.util.matcher.RequestMatcher;
4242
import org.springframework.web.filter.OncePerRequestFilter;
4343
import org.springframework.web.servlet.support.ServletUriComponentsBuilder;
44+
import org.springframework.web.util.UriComponentsBuilder;
4445

4546
import java.io.IOException;
4647
import java.nio.charset.StandardCharsets;
4748
import java.util.Base64;
4849

4950
public final class WebEidMobileAuthInitFilter extends OncePerRequestFilter {
51+
private static final String WEB_EID_MOBILE_AUTH_PATH = "auth";
5052
private static final ObjectWriter OBJECT_WRITER = new ObjectMapper().writer();
5153
private final RequestMatcher requestMatcher;
5254
private final ChallengeNonceGenerator nonceGenerator;
@@ -79,10 +81,20 @@ protected void doFilterInternal(@NonNull HttpServletRequest request,
7981
webEidMobileProperties.requestSigningCert() ? Boolean.TRUE : null)
8082
);
8183
String encoded = Base64.getEncoder().encodeToString(payloadJson.getBytes(StandardCharsets.UTF_8));
82-
String eidAuthUri = "web-eid-mobile://auth#" + encoded;
84+
String authUri = getAuthUri(encoded);
8385

8486
response.setContentType(MediaType.APPLICATION_JSON_VALUE);
85-
OBJECT_WRITER.writeValue(response.getWriter(), new AuthUri(eidAuthUri));
87+
OBJECT_WRITER.writeValue(response.getWriter(), new AuthUri(authUri));
88+
}
89+
90+
private String getAuthUri(String encodedPayload) {
91+
UriComponentsBuilder builder = UriComponentsBuilder.fromUriString(webEidMobileProperties.baseRequestUri());
92+
if (webEidMobileProperties.baseRequestUri().startsWith("http")) {
93+
builder.pathSegment(WEB_EID_MOBILE_AUTH_PATH);
94+
} else {
95+
builder.host(WEB_EID_MOBILE_AUTH_PATH);
96+
}
97+
return builder.fragment(encodedPayload).toUriString();
8698
}
8799

88100
@JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class)
Lines changed: 53 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,42 +1,59 @@
11
<!doctype html>
22
<html lang="en">
3-
<head>
4-
<meta charset="utf-8" />
5-
<title>Signing you in…</title>
6-
<link rel="stylesheet" href="/css/bootstrap.min.css" />
7-
<link rel="stylesheet" href="/css/main.css" />
8-
</head>
9-
<body>
10-
<div id="error-message" class="alert alert-danger" style="display: none" role="alert">
11-
<div class="message"></div>
12-
<pre class="details"></pre>
13-
</div>
3+
<head>
4+
<meta charset="utf-8">
5+
<title>Signing you in…</title>
6+
<link rel="stylesheet" href="/css/bootstrap.min.css"/>
7+
<link rel="stylesheet" href="/css/main.css"/>
8+
</head>
9+
<body>
10+
<div id="error-message" class="alert alert-danger" style="display: none;" role="alert">
11+
<div class="message"></div>
12+
<pre class="details"></pre>
13+
</div>
1414

15-
<script type="module" th:inline="javascript">
16-
import { showErrorMessage, checkHttpError } from "/js/errors.js";
17-
import { parsePayload } from "/js/payload.js";
15+
<script type="module" th:inline="javascript">
16+
import {showErrorMessage, checkHttpError} from "/js/errors.js";
1817

19-
// Using an async IIFE for mobile WebView compatibility:
20-
// top-level await is not supported in some mobile browsers/WebViews.
21-
(async function () {
22-
const payload = parsePayload("Authentication");
23-
const authToken = payload["auth_token"];
24-
const response = await fetch(/*[[${loginProcessingPath}]]*/, {
25-
method: "POST",
26-
headers: {
27-
"Content-Type": "application/json",
28-
"X-CSRF-TOKEN": /*[[${csrfToken}]]*/
29-
},
30-
body: JSON.stringify(authToken),
31-
credentials: "include"
32-
});
33-
await checkHttpError(response);
18+
// Using an async IIFE for mobile WebView compatibility:
19+
// top-level await is not supported in some mobile browsers/WebViews.
20+
(async function () {
21+
const fragment = window.location.hash.slice(1);
22+
if (!fragment) {
23+
throw new Error("Missing authentication payload");
24+
}
3425

35-
window.location.replace("/welcome");
36-
})().catch((error) => {
37-
console.error(error);
38-
showErrorMessage(error);
39-
});
40-
</script>
41-
</body>
26+
let payload;
27+
try {
28+
payload = JSON.parse(atob(fragment));
29+
} catch (e) {
30+
console.error(e)
31+
throw new Error("Failed to parse the authentication response");
32+
}
33+
34+
if (payload.error) {
35+
const error = new Error(payload.message ?? "Authentication failed");
36+
error.code = payload.code;
37+
throw error;
38+
}
39+
40+
const authToken = payload["auth_token"];
41+
const response = await fetch(/*[[${loginProcessingPath}]]*/, {
42+
method: "POST",
43+
headers: {
44+
"Content-Type": "application/json",
45+
"X-CSRF-TOKEN": /*[[${csrfToken}]]*/
46+
},
47+
body: JSON.stringify(authToken),
48+
credentials: "include"
49+
});
50+
await checkHttpError(response);
51+
52+
window.location.replace("/welcome");
53+
})().catch((error) => {
54+
console.error(error);
55+
showErrorMessage(error);
56+
});
57+
</script>
58+
</body>
4259
</html>

0 commit comments

Comments
 (0)