Browse Source

made TokenController configurable

Signed-off-by: Stephan Richter <s.richter@srsoftware.de>
sqlite
Stephan Richter 4 months ago
parent
commit
e7513fee76
  1. 6
      de.srsoftware.oidc.app/src/main/java/de/srsoftware/oidc/app/Application.java
  2. 27
      de.srsoftware.oidc.backend/src/main/java/de/srsoftware/oidc/backend/TokenController.java
  3. 4
      de.srsoftware.utils/src/main/java/de/srsoftware/utils/Optionals.java

6
de.srsoftware.oidc.app/src/main/java/de/srsoftware/oidc/app/Application.java

@ -61,11 +61,11 @@ public class Application {
new Forward(INDEX).bindPath(ROOT).on(server); new Forward(INDEX).bindPath(ROOT).on(server);
new WellKnownController().bindPath(WELL_KNOWN).on(server); new WellKnownController().bindPath(WELL_KNOWN).on(server);
new UserController(fileStore, fileStore).bindPath(API_USER).on(server); new UserController(fileStore, fileStore).bindPath(API_USER).on(server);
new TokenController(fileStore, fileStore, keyManager, fileStore).bindPath(API_TOKEN).on(server); var tokenControllerconfig = new TokenController.Configuration("https://lightoidc.srsoftware.de", 10); // TODO configure or derive from hostname
new TokenController(fileStore, fileStore, keyManager, fileStore, tokenControllerconfig).bindPath(API_TOKEN).on(server);
new ClientController(fileStore, fileStore, fileStore).bindPath(API_CLIENT).on(server); new ClientController(fileStore, fileStore, fileStore).bindPath(API_CLIENT).on(server);
new KeyStoreController(keyStore).bindPath(JWKS).on(server); new KeyStoreController(keyStore).bindPath(JWKS).on(server);
// server.setExecutor(Executors.newCachedThreadPool()); server.setExecutor(Executors.newCachedThreadPool());
server.setExecutor(Executors.newSingleThreadExecutor());
server.start(); server.start();
} }

27
de.srsoftware.oidc.backend/src/main/java/de/srsoftware/oidc/backend/TokenController.java

@ -20,16 +20,20 @@ import org.jose4j.lang.JoseException;
import org.json.JSONObject; import org.json.JSONObject;
public class TokenController extends PathHandler { public class TokenController extends PathHandler {
public record Configuration(String issuer, int tokenExpirationMinutes) {
}
private final ClientService clients; private final ClientService clients;
private final AuthorizationService authorizations; private final AuthorizationService authorizations;
private final UserService users; private final UserService users;
private final KeyManager keyManager; private final KeyManager keyManager;
private Configuration config;
public TokenController(AuthorizationService authorizationService, ClientService clientService, KeyManager keyManager, UserService userService) { public TokenController(AuthorizationService authorizationService, ClientService clientService, KeyManager keyManager, UserService userService, Configuration configuration) {
authorizations = authorizationService; authorizations = authorizationService;
clients = clientService; clients = clientService;
this.keyManager = keyManager; this.keyManager = keyManager;
users = userService; users = userService;
config = configuration;
} }
private Map<String, String> deserialize(String body) { private Map<String, String> deserialize(String body) {
@ -90,7 +94,7 @@ public class TokenController extends PathHandler {
try { try {
PublicJsonWebKey key = keyManager.getKey(); PublicJsonWebKey key = keyManager.getKey();
key.setUse("sig"); key.setUse("sig");
JwtClaims claims = getJwtClaims(user, client); JwtClaims claims = createIdTokenClaims(user, client);
// A JWT is a JWS and/or a JWE with JSON claims as the payload. // A JWT is a JWS and/or a JWE with JSON claims as the payload.
// In this example it is a JWS so we create a JsonWebSignature object. // In this example it is a JWS so we create a JsonWebSignature object.
@ -108,17 +112,20 @@ public class TokenController extends PathHandler {
} }
} }
private static JwtClaims getJwtClaims(User user, Client client) { private JwtClaims createIdTokenClaims(User user, Client client) {
JwtClaims claims = new JwtClaims(); JwtClaims claims = new JwtClaims();
claims.setAudience(client.id(), "test");
// required claims:
claims.setIssuer(config.issuer); // who creates the token and signs it
claims.setSubject(user.uuid()); // the subject/principal is whom the token is about
claims.setAudience(client.id());
claims.setExpirationTimeMinutesInTheFuture(config.tokenExpirationMinutes); // time when the token will expire (10 minutes from now)
claims.setIssuedAtToNow(); // when the token was issued/created (now)
claims.setClaim("client_id", client.id()); claims.setClaim("client_id", client.id());
claims.setClaim("email", user.email()); // additional claims/attributes about the subject can be added claims.setClaim("email", user.email()); // additional claims/attributes about the subject can be added
claims.setExpirationTimeMinutesInTheFuture(10); // time when the token will expire (10 minutes from now)
claims.setIssuedAtToNow(); // when the token was issued/created (now)
claims.setIssuer("https://lightoidc.srsoftware.de"); // who creates the token and signs it
claims.setGeneratedJwtId(); // a unique identifier for the token
claims.setSubject(user.uuid()); // the subject/principal is whom the token is about
client.nonce().ifPresent(nonce -> claims.setClaim(NONCE, nonce)); client.nonce().ifPresent(nonce -> claims.setClaim(NONCE, nonce));
claims.setGeneratedJwtId(); // a unique identifier for the token
return claims; return claims;
} }
} }

4
de.srsoftware.utils/src/main/java/de/srsoftware/utils/Optionals.java

@ -1,9 +1,9 @@
/* © SRSoftware 2024 */ /* © SRSoftware 2024 */
package de.srsoftware.utils; package de.srsoftware.utils;
import java.util.Optional;
import static java.util.Optional.empty; import static java.util.Optional.empty;
import java.util.Optional;
public class Optionals { public class Optionals {
public static <T> Optional<T> nullable(T val) { public static <T> Optional<T> nullable(T val) {
return Optional.ofNullable(val); return Optional.ofNullable(val);

Loading…
Cancel
Save