Skip to content

Commit 228f9d4

Browse files
committed
update lab 4
1 parent 7ed4df1 commit 228f9d4

File tree

8 files changed

+50
-41
lines changed

8 files changed

+50
-41
lines changed

intro-labs/auth-code-demo/README.md

+12
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,18 @@ __Important:__ You can use one of the following users to login:
5151

5252
You may use the _username_ or _email_ in the username input field.
5353

54+
If you stay too long on step 2 (where you have retrieved the authorization code) then you might
55+
get an error when proceeding to step 3 (exchanging the code for an access token).
56+
This is because the authorization code timed out.
57+
58+
According to the [OAuth2 specification](https://tools.ietf.org/html/rfc6749#section-4.1.2):
59+
60+
<blockquote cite="https://tools.ietf.org/html/rfc6749#section-4.1.2">
61+
The authorization code MUST expire shortly after it is issued to mitigate the risk of leaks.
62+
A maximum authorization code lifetime of 10 minutes is RECOMMENDED.
63+
The client MUST NOT use the authorization code more than once.
64+
</blockquote>
65+
5466

5567

5668

intro-labs/auth-code-demo/src/main/java/com/example/authorizationcode/client/jwt/JsonWebToken.java

+12-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
11
package com.example.authorizationcode.client.jwt;
22

3+
import com.fasterxml.jackson.core.JsonProcessingException;
4+
import com.fasterxml.jackson.databind.ObjectMapper;
5+
import com.fasterxml.jackson.databind.SerializationFeature;
36
import org.apache.commons.lang3.StringUtils;
47

8+
import java.io.IOException;
59
import java.util.Base64;
610

711
import static java.nio.charset.StandardCharsets.UTF_8;
@@ -41,7 +45,14 @@ public String getHeader() {
4145
}
4246

4347
public String getPayload() {
44-
return new String(Base64.getDecoder().decode(base64Payload), UTF_8);
48+
String raw_json = new String(Base64.getDecoder().decode(base64Payload), UTF_8);
49+
ObjectMapper mapper = new ObjectMapper();
50+
mapper.configure(SerializationFeature.INDENT_OUTPUT, true);
51+
try {
52+
return mapper.writerWithDefaultPrettyPrinter().writeValueAsString(mapper.readValue(raw_json, Object.class));
53+
} catch (IOException e) {
54+
return raw_json;
55+
}
4556
}
4657

4758
public String getSignature() {

intro-labs/auth-code-demo/src/main/java/com/example/authorizationcode/client/web/TokenIntrospectionController.java

+14-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package com.example.authorizationcode.client.web;
22

3+
import com.fasterxml.jackson.databind.ObjectMapper;
4+
import com.fasterxml.jackson.databind.SerializationFeature;
35
import org.springframework.beans.factory.annotation.Value;
46
import org.springframework.http.MediaType;
57
import org.springframework.stereotype.Controller;
@@ -10,6 +12,7 @@
1012
import org.springframework.web.reactive.function.client.WebClientResponseException;
1113
import reactor.core.publisher.Mono;
1214

15+
import java.io.IOException;
1316
import java.net.URISyntaxException;
1417
import java.net.URL;
1518

@@ -59,7 +62,7 @@ private Mono<String> performTokenIntrospectionRequest(Model model, String tokenR
5962
.bodyToMono(String.class)
6063
.map(
6164
s -> {
62-
model.addAttribute("introspection_response", s);
65+
model.addAttribute("introspection_response", prettyJson(s));
6366
return "introspection";
6467
})
6568
.onErrorResume(
@@ -71,4 +74,14 @@ private Mono<String> performTokenIntrospectionRequest(Model model, String tokenR
7174
return Mono.just("error");
7275
});
7376
}
77+
78+
private String prettyJson(String raw) {
79+
ObjectMapper mapper = new ObjectMapper();
80+
mapper.configure(SerializationFeature.INDENT_OUTPUT, true);
81+
try {
82+
return mapper.writerWithDefaultPrettyPrinter().writeValueAsString(mapper.readValue(raw, Object.class));
83+
} catch (IOException e) {
84+
return raw;
85+
}
86+
}
7487
}

intro-labs/auth-code-demo/src/main/resources/templates/access-token.html

+1-1
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ <h3>Access Token</h3>
3030
<h3>Access Token (decoded JWT)</h3>
3131

3232
<p th:text="'JWT Header: ' + ${jwt_header}"></p>
33-
<p th:text="'JWT Payload: ' + ${jwt_payload}"></p>
33+
<p th:utext="'JWT Payload: ' + ${jwt_payload}"></p>
3434
<p th:text="'JWT Signature: ' + ${jwt_signature}"></p>
3535

3636
<h3>Refresh Token</h3>

lab4/jwt-generator/build.gradle

+1
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ dependencies {
1717
implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
1818
implementation 'org.springframework.boot:spring-boot-starter-web'
1919
implementation 'com.nimbusds:nimbus-jose-jwt:7.0.1'
20+
implementation 'org.apache.commons:commons-lang3'
2021
runtimeOnly 'org.springframework.boot:spring-boot-devtools'
2122
testImplementation 'org.springframework.boot:spring-boot-starter-test'
2223
}

lab4/jwt-generator/src/main/java/com/example/jwt/generator/JwtController.java

+10-9
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import com.nimbusds.jose.crypto.RSASSASigner;
1010
import com.nimbusds.jose.jwk.RSAKey;
1111
import net.minidev.json.JSONObject;
12+
import org.apache.commons.lang3.StringUtils;
1213
import org.springframework.core.io.ClassPathResource;
1314
import org.springframework.stereotype.Controller;
1415
import org.springframework.ui.Model;
@@ -49,16 +50,18 @@ public String generateJwt(User user, Model model) throws JOSEException {
4950
Map<String, Object> payload = new HashMap<>();
5051

5152
payload.put("iss", "test_issuer");
53+
payload.put("exp", Math.abs(System.currentTimeMillis() / 1000) + (5 * 60));
5254
payload.put("aud", new String[] {"library-service"});
53-
payload.put("sub", user.getEmail());
55+
payload.put("sub", user.getEmail() != null ? user.getEmail() : "[email protected]");
5456
payload.put("scope", "openid email profile");
55-
payload.put("groups", new String[] {"library_user"});
56-
payload.put("preferred_username", user.getUsername());
57-
payload.put("given_name", user.getFirstName());
58-
payload.put("family_name", user.getLastName());
59-
payload.put("email", user.getEmail());
57+
payload.put("groups", StringUtils.isNotBlank(user.getRole()) ? new String[] {user.getRole()} : new String[] {"library_user"});
58+
payload.put("preferred_username", StringUtils.isNotBlank(user.getUsername()) ? user.getUsername() : "bwayne");
59+
payload.put("given_name", StringUtils.isNotBlank(user.getFirstName()) ? user.getFirstName() : "Bruce");
60+
payload.put("family_name", StringUtils.isNotBlank(user.getLastName()) ? user.getLastName() : "Wayne");
61+
payload.put("email", StringUtils.isNotBlank(user.getEmail()) ? user.getEmail() : "[email protected]");
6062
payload.put("email_verified", true);
61-
payload.put("name", user.getFirstName() + " " + user.getLastName());
63+
payload.put("name", StringUtils.isNotBlank(user.getFirstName())
64+
&& StringUtils.isNotBlank(user.getLastName()) ? user.getFirstName() + " " + user.getLastName() : "Bruce Wayne");
6265

6366
String jwt = createJwt(payload);
6467
model.addAttribute("jwt", jwt);
@@ -85,6 +88,4 @@ private String createJwt(Map<String, Object> payload) throws JOSEException {
8588
// -jPDm5Iq0SZnjKjCNS5Q15fokXZc8u0A
8689
return jwsObject.serialize();
8790
}
88-
89-
9091
}

lab4/library-server-complete/src/main/java/com/example/library/server/Lab4CompleteLibraryServerApplication.java

-12
This file was deleted.

lab4/library-server-static-complete/README.md

-17
This file was deleted.

0 commit comments

Comments
 (0)