use of io.jans.as.model.common.IntrospectionResponse in project jans by JanssenProject.
the class IntrospectionWsHttpTest method introspectWithValidAuthorizationButInvalidTokenShouldReturnActiveFalse.
@Test
@Parameters({ "umaPatClientId", "umaPatClientSecret" })
public void introspectWithValidAuthorizationButInvalidTokenShouldReturnActiveFalse(final String umaPatClientId, final String umaPatClientSecret) throws Exception {
final Token authorization = UmaClient.requestPat(tokenEndpoint, umaPatClientId, umaPatClientSecret, clientEngine(true));
final IntrospectionService introspectionService = ClientFactory.instance().createIntrospectionService(introspectionEndpoint, clientEngine(true));
final IntrospectionResponse introspectionResponse = introspectionService.introspectToken("Bearer " + authorization.getAccessToken(), "invalid_token");
assertNotNull(introspectionResponse);
assertFalse(introspectionResponse.isActive());
}
use of io.jans.as.model.common.IntrospectionResponse in project jans by JanssenProject.
the class BaseOAuthProtectionService method processAuthorization.
@Override
public Response processAuthorization(HttpHeaders headers, ResourceInfo resourceInfo) {
try {
String token = headers.getHeaderString(HttpHeaders.AUTHORIZATION);
boolean authFound = StringUtils.isNotEmpty(token);
log.info("Authorization header {} found", authFound ? "" : "not");
if (!authFound) {
log.info("Request is missing authorization header");
// see section 3.12 RFC 7644
return IProtectionService.simpleResponse(UNAUTHORIZED, "No authorization header found");
}
token = token.replaceFirst("Bearer\\s+", "");
log.debug("Validating token {}", token);
List<String> scopes = getRequestedScopes(resourceInfo);
log.info("Call requires scopes: {}", scopes);
Jwt jwt = tokenAsJwt(token);
if (jwt == null) {
// Do standard token validation
IntrospectionResponse iresp = null;
try {
iresp = introspectionService.introspectToken("Bearer " + token, token);
} catch (Exception e) {
log.error(e.getMessage());
}
return processIntrospectionResponse(iresp, scopes);
}
// Process the JWT: validate isuer, expiration and signature
JwtClaims claims = jwt.getClaims();
if (!oidcConfig.getIssuer().equals(claims.getClaimAsString(JwtClaimName.ISSUER)))
return IProtectionService.simpleResponse(FORBIDDEN, "Invalid token issuer");
int exp = Optional.ofNullable(claims.getClaimAsInteger(JwtClaimName.EXPIRATION_TIME)).orElse(0);
if (1000L * exp < System.currentTimeMillis())
return IProtectionService.simpleResponse(FORBIDDEN, "Expired token");
Map jwks = mapper.readValue(new URL(oidcConfig.getJwksUri()), Map.class);
// tokenScopes is never null
List<String> tokenScopes = claims.getClaimAsStringList("scope");
AuthCryptoProvider cryptoProvider = new AuthCryptoProvider(null, null, null, true);
SignatureAlgorithm signatureAlg = jwt.getHeader().getSignatureAlgorithm();
if (AlgorithmFamily.HMAC.equals(signatureAlg.getFamily())) {
// It is "expensive" to get the associated client secret
return IProtectionService.simpleResponse(INTERNAL_SERVER_ERROR, "HMAC algorithm not allowed for token signature. Please use an algorithm in the EC, ED, or RSA family for signing");
}
boolean valid = cryptoProvider.verifySignature(jwt.getSigningInput(), jwt.getEncodedSignature(), jwt.getHeader().getKeyId(), new JSONObject(jwks), null, signatureAlg);
if (valid && tokenScopes.containsAll(scopes))
return null;
String msg = "Invalid token signature or insufficient scopes";
log.error("{}. Token scopes: {}", msg, tokenScopes);
// see section 3.12 RFC 7644
return IProtectionService.simpleResponse(FORBIDDEN, msg);
} catch (Exception e) {
log.error(e.getMessage(), e);
return IProtectionService.simpleResponse(INTERNAL_SERVER_ERROR, e.getMessage());
}
}
use of io.jans.as.model.common.IntrospectionResponse in project jans by JanssenProject.
the class IntrospectionService method introspectToken.
private IntrospectionResponse introspectToken(String rpId, String accessToken, boolean retry) {
final String introspectionEndpoint = discoveryService.getConnectDiscoveryResponseByRpId(rpId).getIntrospectionEndpoint();
final ResteasyClient client = ((ResteasyClientBuilder) ResteasyClientBuilder.newBuilder()).httpEngine(httpService.getClientEngine()).build();
final ResteasyWebTarget target = client.target(UriBuilder.fromPath(introspectionEndpoint));
final io.jans.as.client.service.IntrospectionService introspectionService = target.proxy(io.jans.as.client.service.IntrospectionService.class);
try {
IntrospectionResponse response = introspectionService.introspectToken("Bearer " + umaTokenService.getOAuthToken(rpId).getToken(), accessToken);
// we need local variable to force convertion here
return response;
} catch (ClientErrorException e) {
int status = e.getResponse().getStatus();
LOG.debug("Failed to introspect token. Entity: " + e.getResponse().readEntity(String.class) + ", status: " + status, e);
if (retry && (status == 400 || status == 401)) {
LOG.debug("Try maybe OAuthToken is lost on AS, force refresh OAuthToken and re-try ...");
// force to refresh OAuthToken
umaTokenService.obtainOauthToken(rpId);
return introspectToken(rpId, accessToken, false);
} else {
throw e;
}
} catch (Throwable e) {
LOG.trace("Exception during access token introspection.", e);
if (e instanceof ReaderException) {
// dummy construction but checked JsonParseException is thrown inside jackson provider, so we don't have choice
// trying to handle compatiblity issue.
LOG.trace("Trying to handle compatibility issue ...");
BackCompatibleIntrospectionService backCompatibleIntrospectionService = ClientFactory.instance().createBackCompatibleIntrospectionService(introspectionEndpoint, httpService.getClientEngine());
BackCompatibleIntrospectionResponse backResponse = backCompatibleIntrospectionService.introspectToken("Bearer " + umaTokenService.getOAuthToken(rpId).getToken(), accessToken);
LOG.trace("Handled compatibility issue. Response: " + backResponse);
IntrospectionResponse response = new IntrospectionResponse();
response.setSub(backResponse.getSubject());
response.setAudience(backResponse.getAudience());
response.setTokenType(backResponse.getTokenType());
response.setActive(backResponse.isActive());
response.setScope(backResponse.getScopes());
if (!backResponse.getScope().isEmpty()) {
response.setScope(backResponse.getScope());
}
response.setIssuer(backResponse.getIssuer());
response.setUsername(backResponse.getUsername());
response.setClientId(backResponse.getClientId());
response.setJti(backResponse.getJti());
response.setAcrValues(backResponse.getAcrValues());
response.setExpiresAt(dateToSeconds(backResponse.getExpiresAt()));
response.setIssuedAt(dateToSeconds(backResponse.getIssuedAt()));
return response;
}
throw e;
}
}
use of io.jans.as.model.common.IntrospectionResponse in project jans by JanssenProject.
the class IntrospectAccessTokenOperation method execute.
@Override
public IOpResponse execute(IntrospectAccessTokenParams params) {
getValidationService().validate(params);
final IntrospectionService introspectionService = getInstance(IntrospectionService.class);
IntrospectionResponse response = introspectionService.introspectToken(params.getRpId(), params.getAccessToken());
return new POJOResponse(response);
}
use of io.jans.as.model.common.IntrospectionResponse in project jans by JanssenProject.
the class AuthClientFactory method getIntrospectionEndpoint.
public static String getIntrospectionEndpoint(String issuer) throws JsonProcessingException {
log.debug(" Get Introspection Endpoint - issuer:{}", issuer);
String configurationEndpoint = issuer + "/.well-known/openid-configuration";
Builder introspectionClient = getClientBuilder(configurationEndpoint);
introspectionClient.header(CONTENT_TYPE, MediaType.APPLICATION_JSON);
Response introspectionResponse = introspectionClient.get();
log.trace("AuthClientFactory::getIntrospectionEndpoint() - introspectionResponse:{}", introspectionResponse);
if (introspectionResponse.getStatus() == 200) {
String introspectionEntity = introspectionResponse.readEntity(String.class);
log.trace("AuthClientFactory::getIntrospectionEndpoint() - introspectionEntity:{}", introspectionEntity);
return Jackson.getElement(introspectionEntity, "introspection_endpoint");
}
return null;
}
Aggregations