use of org.apereo.cas.ticket.accesstoken.AccessToken in project cas by apereo.
the class OAuth20AuthorizeControllerTests method verifyTokenRedirectToClientWithState.
@Test
public void verifyTokenRedirectToClientWithState() throws Exception {
clearAllServices();
final MockHttpServletRequest mockRequest = new MockHttpServletRequest(GET, CONTEXT + OAuthConstants.AUTHORIZE_URL);
mockRequest.setParameter(OAuthConstants.CLIENT_ID, CLIENT_ID);
mockRequest.setParameter(OAuthConstants.REDIRECT_URI, REDIRECT_URI);
mockRequest.setParameter(OAuthConstants.RESPONSE_TYPE, OAuth20ResponseTypes.TOKEN.name().toLowerCase());
mockRequest.setServerName(CAS_SERVER);
mockRequest.setServerPort(CAS_PORT);
mockRequest.setScheme(CAS_SCHEME);
mockRequest.setParameter(OAuthConstants.STATE, STATE);
final MockHttpServletResponse mockResponse = new MockHttpServletResponse();
final OAuthRegisteredService service = getRegisteredService(REDIRECT_URI, SERVICE_NAME);
service.setBypassApprovalPrompt(true);
oAuth20AuthorizeEndpointController.getServicesManager().save(service);
final CasProfile profile = new CasProfile();
profile.setId(ID);
final Map<String, Object> attributes = new HashMap<>();
attributes.put(FIRST_NAME_ATTRIBUTE, FIRST_NAME);
attributes.put(LAST_NAME_ATTRIBUTE, LAST_NAME);
profile.addAttributes(attributes);
final MockHttpSession session = new MockHttpSession();
mockRequest.setSession(session);
session.putValue(Pac4jConstants.USER_PROFILES, profile);
final ModelAndView modelAndView = oAuth20AuthorizeEndpointController.handleRequestInternal(mockRequest, mockResponse);
final View view = modelAndView.getView();
assertTrue(view instanceof RedirectView);
final RedirectView redirectView = (RedirectView) view;
final String redirectUrl = redirectView.getUrl();
assertTrue(redirectUrl.startsWith(REDIRECT_URI + "#access_token="));
assertTrue(redirectUrl.contains('&' + OAuthConstants.STATE + '=' + STATE));
final String code = StringUtils.substringBetween(redirectUrl, "#access_token=", "&token_type=bearer");
final AccessToken accessToken = (AccessToken) oAuth20AuthorizeEndpointController.getTicketRegistry().getTicket(code);
assertNotNull(accessToken);
final Principal principal = accessToken.getAuthentication().getPrincipal();
assertEquals(ID, principal.getId());
final Map<String, Object> principalAttributes = principal.getAttributes();
assertEquals(attributes.size(), principalAttributes.size());
assertEquals(FIRST_NAME, principalAttributes.get(FIRST_NAME_ATTRIBUTE));
}
use of org.apereo.cas.ticket.accesstoken.AccessToken in project cas by apereo.
the class BaseOAuthWrapperController method generateAccessToken.
/**
* Generate an access token from a service and authentication.
*
* @param service the service
* @param authentication the authentication
* @param context the context
* @return an access token
*/
protected AccessToken generateAccessToken(final Service service, final Authentication authentication, final J2EContext context) {
final AccessToken accessToken = this.accessTokenFactory.create(service, authentication);
LOGGER.debug("Creating access token [{}]", accessToken);
this.ticketRegistry.addTicket(accessToken);
LOGGER.debug("Added access token [{}] to registry", accessToken);
return accessToken;
}
use of org.apereo.cas.ticket.accesstoken.AccessToken in project cas by apereo.
the class OAuth20AccessTokenEndpointController method handleRequestInternal.
/**
* Handle request internal model and view.
*
* @param request the request
* @param response the response
* @return the model and view
* @throws Exception the exception
*/
@PostMapping(path = OAuthConstants.BASE_OAUTH20_URL + '/' + OAuthConstants.ACCESS_TOKEN_URL)
public ModelAndView handleRequestInternal(final HttpServletRequest request, final HttpServletResponse response) throws Exception {
try {
response.setContentType(MediaType.TEXT_PLAIN_VALUE);
if (!verifyAccessTokenRequest(request, response)) {
LOGGER.error("Access token request verification fails");
return OAuthUtils.writeTextError(response, OAuthConstants.INVALID_REQUEST);
}
final String grantType = request.getParameter(OAuthConstants.GRANT_TYPE);
final Service service;
final Authentication authentication;
final boolean generateRefreshToken;
final OAuthRegisteredService registeredService;
final J2EContext context = WebUtils.getPac4jJ2EContext(request, response);
final ProfileManager manager = WebUtils.getPac4jProfileManager(request, response);
if (isGrantType(grantType, OAuth20GrantTypes.AUTHORIZATION_CODE) || isGrantType(grantType, OAuth20GrantTypes.REFRESH_TOKEN)) {
final Optional<UserProfile> profile = manager.get(true);
final String clientId = profile.get().getId();
registeredService = OAuthUtils.getRegisteredOAuthService(getServicesManager(), clientId);
// we generate a refresh token if requested by the service but not from a refresh token
generateRefreshToken = registeredService != null && registeredService.isGenerateRefreshToken() && isGrantType(grantType, OAuth20GrantTypes.AUTHORIZATION_CODE);
final String parameterName;
if (isGrantType(grantType, OAuth20GrantTypes.AUTHORIZATION_CODE)) {
parameterName = OAuthConstants.CODE;
} else {
parameterName = OAuthConstants.REFRESH_TOKEN;
}
final OAuthToken token = getToken(request, parameterName);
if (token == null) {
LOGGER.error("No token found for authorization_code or refresh_token grant types");
return OAuthUtils.writeTextError(response, OAuthConstants.INVALID_GRANT);
}
service = token.getService();
authentication = token.getAuthentication();
} else {
final String clientId = request.getParameter(OAuthConstants.CLIENT_ID);
registeredService = OAuthUtils.getRegisteredOAuthService(getServicesManager(), clientId);
generateRefreshToken = registeredService != null && registeredService.isGenerateRefreshToken();
try {
// resource owner password grant type
final Optional<OAuthUserProfile> profile = manager.get(true);
if (!profile.isPresent()) {
throw new UnauthorizedServiceException("OAuth user profile cannot be determined");
}
service = createService(registeredService, context);
authentication = createAuthentication(profile.get(), registeredService, context, service);
RegisteredServiceAccessStrategyUtils.ensurePrincipalAccessIsAllowedForService(service, registeredService, authentication);
} catch (final Exception e) {
LOGGER.error(e.getMessage(), e);
return OAuthUtils.writeTextError(response, OAuthConstants.INVALID_GRANT);
}
}
final AccessToken accessToken = generateAccessToken(service, authentication, context);
RefreshToken refreshToken = null;
if (generateRefreshToken) {
refreshToken = this.refreshTokenFactory.create(service, authentication);
getTicketRegistry().addTicket(refreshToken);
}
LOGGER.debug("access token: [{}] / timeout: [{}] / refresh token: [{}]", accessToken, casProperties.getTicket().getTgt().getTimeToKillInSeconds(), refreshToken);
final String responseType = context.getRequestParameter(OAuthConstants.RESPONSE_TYPE);
final OAuth20ResponseTypes type = Arrays.stream(OAuth20ResponseTypes.values()).filter(t -> t.getType().equalsIgnoreCase(responseType)).findFirst().orElse(OAuth20ResponseTypes.CODE);
this.accessTokenResponseGenerator.generate(request, response, registeredService, service, accessToken, refreshToken, casProperties.getTicket().getTgt().getTimeToKillInSeconds(), type);
getTicketRegistry().addTicket(accessToken);
response.setStatus(HttpServletResponse.SC_OK);
return null;
} catch (final Exception e) {
LOGGER.error(e.getMessage(), e);
throw Throwables.propagate(e);
}
}
use of org.apereo.cas.ticket.accesstoken.AccessToken in project cas by apereo.
the class OidcIdTokenGeneratorService method produceIdTokenClaims.
/**
* Produce id token claims jwt claims.
*
* @param request the request
* @param accessTokenId the access token id
* @param timeout the timeout
* @param service the service
* @param profile the user profile
* @param context the context
* @param responseType the response type
* @return the jwt claims
*/
protected JwtClaims produceIdTokenClaims(final HttpServletRequest request, final AccessToken accessTokenId, final long timeout, final OidcRegisteredService service, final UserProfile profile, final J2EContext context, final OAuth20ResponseTypes responseType) {
final Authentication authentication = accessTokenId.getAuthentication();
final Principal principal = authentication.getPrincipal();
final JwtClaims claims = new JwtClaims();
claims.setJwtId(UUID.randomUUID().toString());
claims.setIssuer(this.issuer);
claims.setAudience(service.getClientId());
final NumericDate expirationDate = NumericDate.now();
expirationDate.addSeconds(timeout);
claims.setExpirationTime(expirationDate);
claims.setIssuedAtToNow();
claims.setNotBeforeMinutesInThePast(this.skew);
claims.setSubject(principal.getId());
if (authentication.getAttributes().containsKey(casProperties.getAuthn().getMfa().getAuthenticationContextAttribute())) {
final Collection<Object> val = CollectionUtils.toCollection(authentication.getAttributes().get(casProperties.getAuthn().getMfa().getAuthenticationContextAttribute()));
claims.setStringClaim(OidcConstants.ACR, val.iterator().next().toString());
}
if (authentication.getAttributes().containsKey(AuthenticationHandler.SUCCESSFUL_AUTHENTICATION_HANDLERS)) {
final Collection<Object> val = CollectionUtils.toCollection(authentication.getAttributes().get(AuthenticationHandler.SUCCESSFUL_AUTHENTICATION_HANDLERS));
claims.setStringListClaim(OidcConstants.AMR, val.toArray(new String[] {}));
}
claims.setClaim(OAuthConstants.STATE, authentication.getAttributes().get(OAuthConstants.STATE));
claims.setClaim(OAuthConstants.NONCE, authentication.getAttributes().get(OAuthConstants.NONCE));
claims.setClaim(OidcConstants.CLAIM_AT_HASH, generateAccessTokenHash(accessTokenId, service));
principal.getAttributes().entrySet().stream().filter(entry -> casProperties.getAuthn().getOidc().getClaims().contains(entry.getKey())).forEach(entry -> claims.setClaim(entry.getKey(), entry.getValue()));
if (!claims.hasClaim(OidcConstants.CLAIM_PREFERRED_USERNAME)) {
claims.setClaim(OidcConstants.CLAIM_PREFERRED_USERNAME, profile.getId());
}
return claims;
}
use of org.apereo.cas.ticket.accesstoken.AccessToken in project cas by apereo.
the class OAuth20UserProfileControllerController method handleRequestInternal.
/**
* Handle request internal response entity.
*
* @param request the request
* @param response the response
* @return the response entity
* @throws Exception the exception
*/
@GetMapping(path = OAuthConstants.BASE_OAUTH20_URL + '/' + OAuthConstants.PROFILE_URL, produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<String> handleRequestInternal(final HttpServletRequest request, final HttpServletResponse response) throws Exception {
response.setContentType(MediaType.APPLICATION_JSON_VALUE);
String accessToken = request.getParameter(OAuthConstants.ACCESS_TOKEN);
if (StringUtils.isBlank(accessToken)) {
final String authHeader = request.getHeader(HttpConstants.AUTHORIZATION_HEADER);
if (StringUtils.isNotBlank(authHeader) && authHeader.toLowerCase().startsWith(OAuthConstants.BEARER_TOKEN.toLowerCase() + ' ')) {
accessToken = authHeader.substring(OAuthConstants.BEARER_TOKEN.length() + 1);
}
}
LOGGER.debug("[{}]: [{}]", OAuthConstants.ACCESS_TOKEN, accessToken);
if (StringUtils.isBlank(accessToken)) {
LOGGER.error("Missing [{}]", OAuthConstants.ACCESS_TOKEN);
final LinkedMultiValueMap<String, String> map = new LinkedMultiValueMap<>(1);
map.add(OAuthConstants.ERROR, OAuthConstants.MISSING_ACCESS_TOKEN);
final String value = OAuthUtils.jsonify(map);
return new ResponseEntity<>(value, HttpStatus.UNAUTHORIZED);
}
final AccessToken accessTokenTicket = getTicketRegistry().getTicket(accessToken, AccessToken.class);
if (accessTokenTicket == null || accessTokenTicket.isExpired()) {
LOGGER.error("Expired access token: [{}]", OAuthConstants.ACCESS_TOKEN);
final LinkedMultiValueMap<String, String> map = new LinkedMultiValueMap<>(1);
map.add(OAuthConstants.ERROR, OAuthConstants.EXPIRED_ACCESS_TOKEN);
final String value = OAuthUtils.jsonify(map);
return new ResponseEntity<>(value, HttpStatus.UNAUTHORIZED);
}
final Map<String, Object> map = writeOutProfileResponse(accessTokenTicket.getAuthentication(), accessTokenTicket.getAuthentication().getPrincipal());
final String value = OAuthUtils.jsonify(map);
LOGGER.debug("Final user profile is [{}]", value);
return new ResponseEntity<>(value, HttpStatus.OK);
}
Aggregations