tied nonce to AuthorizationService by dedicated methods

Signed-off-by: Stephan Richter <s.richter@srsoftware.de>
This commit is contained in:
2024-09-16 23:56:29 +02:00
parent f737c1dc50
commit 8bfaf22084
7 changed files with 71 additions and 47 deletions

View File

@@ -37,6 +37,7 @@ public class FileStore implements AuthorizationService, ClientService, SessionSe
private final PasswordHasher<String> passwordHasher;
private Map<String, AccessToken> accessTokens = new HashMap<>();
private Map<String, Authorization> authCodes = new HashMap<>();
private Map<String, String> nonceMap = new HashMap<>();
private Authenticator auth;
public FileStore(File storage, PasswordHasher<String> passwordHasher) throws IOException {
@@ -72,16 +73,15 @@ public class FileStore implements AuthorizationService, ClientService, SessionSe
var clients = authorizations.getJSONObject(userId);
var clientIds = Set.copyOf(clients.keySet());
for (var clientId : clientIds) {
var clientData = clients.getJSONObject(clientId);
var scopeMap = clientData.getJSONObject(SCOPE);
var scopes = Set.copyOf(scopeMap.keySet());
var client = clients.getJSONObject(clientId);
var scopes = Set.copyOf(client.keySet());
for (var scope : scopes) {
var expiration = Instant.ofEpochSecond(scopeMap.getLong(scope));
var expiration = Instant.ofEpochSecond(client.getLong(scope));
if (expiration.isBefore(now)) {
scopeMap.remove(scope);
client.remove(scope);
}
}
if (scopeMap.isEmpty()) clients.remove(clientId);
if (client.isEmpty()) clients.remove(clientId);
}
if (clients.isEmpty()) authorizations.remove(userId);
}
@@ -298,7 +298,7 @@ public class FileStore implements AuthorizationService, ClientService, SessionSe
@Override
public ClientService save(Client client) {
if (!json.has(CLIENTS)) json.put(CLIENTS, new JSONObject());
json.getJSONObject(CLIENTS).put(client.id(), client.map());
json.getJSONObject(CLIENTS).put(client.id(), Map.of(NAME, client.name(), SECRET, client.secret(), REDIRECT_URIS, client.redirectUris()));
save();
return this;
}
@@ -311,7 +311,7 @@ public class FileStore implements AuthorizationService, ClientService, SessionSe
return new Client(clientId, clientData.getString(NAME), clientData.getString(SECRET), redirectUris);
}
/*** ClaimAuthorizationService methods ***/
/*** AuthorizationService methods ***/
private String authCode(Authorization authorization) {
var code = uuid();
authCodes.put(code, authorization);
@@ -319,20 +319,13 @@ public class FileStore implements AuthorizationService, ClientService, SessionSe
}
@Override
public AuthorizationService authorize(String userId, String clientId, Collection<String> scopes, String nonce, Instant expiration) {
public AuthorizationService authorize(String userId, String clientId, Collection<String> scopes, Instant expiration) {
if (!json.has(AUTHORIZATIONS)) json.put(AUTHORIZATIONS, new JSONObject());
var authorizations = json.getJSONObject(AUTHORIZATIONS);
if (!authorizations.has(userId)) authorizations.put(userId, new JSONObject());
var userAuthorizations = authorizations.getJSONObject(userId);
if (!userAuthorizations.has(clientId)) userAuthorizations.put(clientId, new JSONObject());
var clientData = userAuthorizations.getJSONObject(clientId);
if (nonce != null) {
clientData.put(NONCE, nonce);
} else {
if (clientData.has(NONCE)) clientData.remove(NONCE);
}
if (!clientData.has(SCOPE)) clientData.put(SCOPE, new JSONObject());
var clientScopes = clientData.getJSONObject(SCOPE);
var clientScopes = userAuthorizations.getJSONObject(clientId);
for (var scope : scopes) clientScopes.put(scope, expiration.getEpochSecond());
save();
return this;
@@ -344,15 +337,19 @@ public class FileStore implements AuthorizationService, ClientService, SessionSe
return nullable(authCodes.remove(authCode));
}
@Override
public Optional<String> consumeNonce(String userId, String clientId) {
var nonceKey = String.join("@", userId, clientId);
return nullable(nonceMap.get(nonceKey));
}
@Override
public AuthResult getAuthorization(String userId, String clientId, Collection<String> scopes) {
if (!json.has(AUTHORIZATIONS)) return unauthorized(scopes);
var authorizations = json.getJSONObject(AUTHORIZATIONS);
var userAuthorizations = authorizations.has(userId) ? authorizations.getJSONObject(userId) : null;
if (userAuthorizations == null) return unauthorized(scopes);
var clientData = userAuthorizations.has(clientId) ? userAuthorizations.getJSONObject(clientId) : null;
if (clientData == null) return unauthorized(scopes);
var clientScopes = clientData.has(SCOPE) ? clientData.getJSONObject(SCOPE) : null;
var clientScopes = userAuthorizations.has(clientId) ? userAuthorizations.getJSONObject(clientId) : null;
if (clientScopes == null) return unauthorized(scopes);
var now = Instant.now();
var authorizedScopes = new HashSet<String>();
@@ -371,11 +368,19 @@ public class FileStore implements AuthorizationService, ClientService, SessionSe
}
if (authorizedScopes.isEmpty()) return unauthorized(scopes);
String nonce = clientData.has(NONCE) ? clientData.getString(NONCE) : null;
var authorization = new Authorization(clientId, userId, new AuthorizedScopes(authorizedScopes, earliestExpiration), nonce);
var authorization = new Authorization(clientId, userId, new AuthorizedScopes(authorizedScopes, earliestExpiration));
return new AuthResult(authorization.scopes(), unauthorizedScopes, authCode(authorization));
}
@Override
public void nonce(String userId, String clientId, String nonce) {
var nonceKey = String.join("@", userId, clientId);
if (nonce != null) {
nonceMap.put(nonceKey, nonce);
} else
nonceMap.remove(nonceKey);
}
private AuthResult unauthorized(Collection<String> scopes) {
return new AuthResult(null, new HashSet<>(scopes), null);
}