use of oidc.model.AccessToken in project OpenConext-oidcng by OpenConext.
the class AuthorizationEndpoint method authorizationEndpointResponse.
private Map<String, Object> authorizationEndpointResponse(User user, OpenIDClient client, AuthorizationRequest authorizationRequest, List<String> scopes, ResponseType responseType, State state) {
Map<String, Object> result = new LinkedHashMap<>();
EncryptedTokenValue encryptedAccessToken = tokenGenerator.generateAccessTokenWithEmbeddedUserInfo(user, client, scopes);
if (responseType.contains(ResponseType.Value.TOKEN.getValue()) || !isOpenIDRequest(authorizationRequest)) {
String unspecifiedUrnHash = KeyGenerator.oneWayHash(user.getUnspecifiedNameId(), this.salt);
AccessToken accessToken = new AccessToken(encryptedAccessToken.getJwtId(), user.getSub(), client.getClientId(), scopes, encryptedAccessToken.getKeyId(), accessTokenValidity(client), false, null, unspecifiedUrnHash);
accessTokenRepository.insert(accessToken);
result.put("access_token", encryptedAccessToken.getValue());
result.put("token_type", "Bearer");
}
if (responseType.contains(ResponseType.Value.CODE.getValue())) {
AuthorizationCode authorizationCode = createAndSaveAuthorizationCode(authorizationRequest, client, user);
result.put("code", authorizationCode.getCode());
}
if (responseType.contains(OIDCResponseTypeValue.ID_TOKEN.getValue()) && isOpenIDRequest(scopes) && isOpenIDRequest(authorizationRequest)) {
AuthenticationRequest authenticationRequest = (AuthenticationRequest) authorizationRequest;
List<String> claims = getClaims(authorizationRequest);
TokenValue tokenValue = tokenGenerator.generateIDTokenForAuthorizationEndpoint(user, client, authenticationRequest.getNonce(), responseType, encryptedAccessToken.getValue(), claims, Optional.ofNullable((String) result.get("code")), state);
result.put("id_token", tokenValue.getValue());
}
result.put("expires_in", client.getAccessTokenValidity());
if (state != null) {
result.put("state", state.getValue());
}
return result;
}
use of oidc.model.AccessToken in project OpenConext-oidcng by OpenConext.
the class IntrospectEndpoint method introspect.
@PostMapping(value = { "oidc/introspect" }, consumes = { MediaType.APPLICATION_FORM_URLENCODED_VALUE })
public ResponseEntity<Map<String, Object>> introspect(HttpServletRequest request) throws ParseException, IOException, java.text.ParseException {
HTTPRequest httpRequest = ServletUtils.createHTTPRequest(request);
TokenIntrospectionRequest tokenIntrospectionRequest = TokenIntrospectionRequest.parse(httpRequest);
ClientAuthentication clientAuthentication = tokenIntrospectionRequest.getClientAuthentication();
String accessTokenValue = tokenIntrospectionRequest.getToken().getValue();
// https://tools.ietf.org/html/rfc7662 is vague about the authorization requirements, but we enforce basic auth
if (!(clientAuthentication instanceof PlainClientSecret)) {
LOG.warn("No authentication present");
throw new UnauthorizedException("Invalid user / secret");
}
String clientId = clientAuthentication.getClientID().getValue();
OpenIDClient resourceServer = openIDClientRepository.findOptionalByClientId(clientId).orElseThrow(() -> new UnknownClientException(clientId));
MDCContext.mdcContext("action", "Introspect", "rp", resourceServer.getClientId(), "accessTokenValue", accessTokenValue);
if (!secretsMatch((PlainClientSecret) clientAuthentication, resourceServer)) {
LOG.warn("Secret does not match for RS " + resourceServer.getClientId());
throw new UnauthorizedException("Invalid user / secret");
}
if (!resourceServer.isResourceServer()) {
LOG.warn("RS required for not configured for RP " + resourceServer.getClientId());
throw new UnauthorizedException("Requires ResourceServer");
}
Optional<SignedJWT> optionalSignedJWT = tokenGenerator.parseAndValidateSignedJWT(accessTokenValue);
if (!optionalSignedJWT.isPresent()) {
LOG.warn("Invalid access_token " + accessTokenValue);
return ResponseEntity.ok(Collections.singletonMap("active", false));
}
SignedJWT signedJWT = optionalSignedJWT.get();
String jwtId = signedJWT.getJWTClaimsSet().getJWTID();
Optional<AccessToken> optionalAccessToken = accessTokenRepository.findByJwtId(jwtId);
if (!optionalAccessToken.isPresent()) {
LOG.warn("No access_token found " + accessTokenValue);
return ResponseEntity.ok(Collections.singletonMap("active", false));
}
AccessToken accessToken = optionalAccessToken.get();
if (accessToken.isExpired(Clock.systemDefaultZone())) {
LOG.warn("Access token is expired " + accessTokenValue);
return ResponseEntity.ok(Collections.singletonMap("active", false));
}
List<String> scopes = accessToken.getScopes();
Map<String, Object> result = new TreeMap<>();
boolean isUserAccessToken = !accessToken.isClientCredentials();
if (isUserAccessToken) {
OpenIDClient openIDClient = openIDClientRepository.findOptionalByClientId(accessToken.getClientId()).orElseThrow(() -> new UnknownClientException(accessToken.getClientId()));
if (!openIDClient.getClientId().equals(resourceServer.getClientId()) && !openIDClient.getAllowedResourceServers().contains(resourceServer.getClientId())) {
throw new UnauthorizedException(String.format("RP %s is not allowed to use the API of resource server %s. Allowed resource servers are %s", accessToken.getClientId(), resourceServer.getClientId(), openIDClient.getAllowedResourceServers()));
}
User user = tokenGenerator.decryptAccessTokenWithEmbeddedUserInfo(signedJWT);
result.put("updated_at", user.getUpdatedAt());
if (resourceServer.isIncludeUnspecifiedNameID()) {
result.put("unspecified_id", user.getUnspecifiedNameId());
}
result.put("authenticating_authority", user.getAuthenticatingAuthority());
result.put("sub", user.getSub());
result.putAll(user.getAttributes());
List<String> acrClaims = user.getAcrClaims();
if (!CollectionUtils.isEmpty(acrClaims)) {
result.put("acr", String.join(" ", acrClaims));
}
boolean validPseudonymisation = validPseudonymisation(result, resourceServer, openIDClient);
if (!validPseudonymisation && enforceEduidResourceServerLinkedAccount) {
LOG.warn(String.format("Pseudonymisation failed. No eduperson_principal_name for RS %s", resourceServer.getClientId()));
return ResponseEntity.ok(Collections.singletonMap("active", false));
}
}
// The following claims can not be overridden by the
result.put("active", true);
result.put("scope", String.join(" ", scopes));
result.put("client_id", accessToken.getClientId());
result.put("exp", accessToken.getExpiresIn().getTime() / 1000L);
result.put("sub", accessToken.getSub());
result.put("iss", issuer);
result.put("token_type", "Bearer");
LOG.debug(String.format("Returning introspect active %s for RS %s", true, resourceServer.getClientId()));
return ResponseEntity.ok(result);
}
use of oidc.model.AccessToken in project OpenConext-oidcng by OpenConext.
the class TokenController method convertToken.
private Map<String, Object> convertToken(AccessToken token) {
Map<String, Object> result = new HashMap<>();
result.put("id", token.getId());
Optional<OpenIDClient> optionalClient = openIDClientRepository.findOptionalByClientId(token.getClientId());
if (!optionalClient.isPresent()) {
return result;
}
OpenIDClient openIDClient = optionalClient.get();
result.put("clientId", openIDClient.getClientId());
result.put("clientName", openIDClient.getName());
List<OpenIDClient> resourceServers = openIDClient.getAllowedResourceServers().stream().map(rs -> openIDClientRepository.findOptionalByClientId(rs)).filter(Optional::isPresent).map(Optional::get).collect(toList());
result.put("audiences", resourceServers.stream().map(OpenIDClient::getName));
result.put("createdAt", token.getCreatedAt());
result.put("expiresIn", token.getExpiresIn());
result.put("type", token instanceof RefreshToken ? TokenType.REFRESH : TokenType.ACCESS);
Map<String, Scope> allScopes = resourceServers.stream().map(OpenIDClient::getScopes).flatMap(List::stream).filter(distinctByKey(Scope::getName)).collect(toMap(Scope::getName, s -> s));
List<Scope> scopes = token.getScopes().stream().filter(name -> !name.equalsIgnoreCase("openid")).map(allScopes::get).filter(Objects::nonNull).collect(toList());
result.put("scopes", scopes);
return result;
}
use of oidc.model.AccessToken in project OpenConext-oidcng by OpenConext.
the class KeyRolloverTest method rolloverSigningKeys.
@Test
public void rolloverSigningKeys() throws GeneralSecurityException, ParseException, IOException {
resetAndCreateSigningKeys(3);
final List<String> signingKeys = mongoTemplate.findAll(SigningKey.class).stream().map(SigningKey::getKeyId).sorted().collect(toList());
assertEquals(3, signingKeys.size());
List<AccessToken> tokens = IntStream.rangeClosed(0, 10).mapToObj(i -> accessToken("val" + i, signingKeys.get(i % 2))).collect(toList());
mongoTemplate.bulkOps(BulkOperations.BulkMode.ORDERED, AccessToken.class).remove(new Query()).insert(tokens).execute();
KeyRollover keyRollover = new KeyRollover(tokenGenerator, mongoTemplate, true, sequenceRepository);
keyRollover.rollover();
List<String> keys = mongoTemplate.findAll(SigningKey.class).stream().map(SigningKey::getKeyId).sorted().collect(toList());
// would expect 4, but one signing key is cleaned up as it is not used in
assertEquals(3, keys.size());
}
use of oidc.model.AccessToken in project OpenConext-oidcng by OpenConext.
the class AccessTokenRepositoryTest method findByValue.
@Test
public void findByValue() {
String jwtId = UUID.randomUUID().toString();
accessTokenRepository.insert(accessToken(jwtId, new Date()));
AccessToken accessToken = accessTokenRepository.findByJwtId(jwtId).get();
assertEquals(jwtId, accessToken.getJwtId());
}
Aggregations