Search in sources :

Example 1 with AccessToken

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));
}
Also used : CasProfile(org.pac4j.cas.profile.CasProfile) HashMap(java.util.HashMap) MockHttpServletRequest(org.springframework.mock.web.MockHttpServletRequest) OAuthRegisteredService(org.apereo.cas.support.oauth.services.OAuthRegisteredService) ModelAndView(org.springframework.web.servlet.ModelAndView) RedirectView(org.springframework.web.servlet.view.RedirectView) ModelAndView(org.springframework.web.servlet.ModelAndView) View(org.springframework.web.servlet.View) AccessToken(org.apereo.cas.ticket.accesstoken.AccessToken) RedirectView(org.springframework.web.servlet.view.RedirectView) MockHttpSession(org.springframework.mock.web.MockHttpSession) MockHttpServletResponse(org.springframework.mock.web.MockHttpServletResponse) Principal(org.apereo.cas.authentication.principal.Principal) Test(org.junit.Test)

Example 2 with AccessToken

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;
}
Also used : AccessToken(org.apereo.cas.ticket.accesstoken.AccessToken)

Example 3 with 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);
    }
}
Also used : ProfileManager(org.pac4j.core.profile.ProfileManager) OAuth20ResponseTypes(org.apereo.cas.support.oauth.OAuth20ResponseTypes) OAuthUserProfile(org.apereo.cas.support.oauth.profile.OAuthUserProfile) UserProfile(org.pac4j.core.profile.UserProfile) OAuthRegisteredService(org.apereo.cas.support.oauth.services.OAuthRegisteredService) WebApplicationService(org.apereo.cas.authentication.principal.WebApplicationService) OAuthRegisteredService(org.apereo.cas.support.oauth.services.OAuthRegisteredService) Service(org.apereo.cas.authentication.principal.Service) UnauthorizedServiceException(org.apereo.cas.services.UnauthorizedServiceException) J2EContext(org.pac4j.core.context.J2EContext) UnauthorizedServiceException(org.apereo.cas.services.UnauthorizedServiceException) OAuthToken(org.apereo.cas.ticket.OAuthToken) RefreshToken(org.apereo.cas.ticket.refreshtoken.RefreshToken) Authentication(org.apereo.cas.authentication.Authentication) AccessToken(org.apereo.cas.ticket.accesstoken.AccessToken) OAuthUserProfile(org.apereo.cas.support.oauth.profile.OAuthUserProfile) PostMapping(org.springframework.web.bind.annotation.PostMapping)

Example 4 with AccessToken

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;
}
Also used : CasConfigurationProperties(org.apereo.cas.configuration.CasConfigurationProperties) Arrays(java.util.Arrays) AlgorithmIdentifiers(org.jose4j.jws.AlgorithmIdentifiers) LoggerFactory(org.slf4j.LoggerFactory) DigestUtils(org.apereo.cas.util.DigestUtils) Autowired(org.springframework.beans.factory.annotation.Autowired) HttpServletRequest(javax.servlet.http.HttpServletRequest) AuthenticationHandler(org.apereo.cas.authentication.AuthenticationHandler) Authentication(org.apereo.cas.authentication.Authentication) CollectionUtils(org.apereo.cas.util.CollectionUtils) AccessToken(org.apereo.cas.ticket.accesstoken.AccessToken) OAuth20ResponseTypes(org.apereo.cas.support.oauth.OAuth20ResponseTypes) Logger(org.slf4j.Logger) OidcConstants(org.apereo.cas.oidc.OidcConstants) Collection(java.util.Collection) OAuthConstants(org.apereo.cas.support.oauth.OAuthConstants) HttpServletResponse(javax.servlet.http.HttpServletResponse) UUID(java.util.UUID) OAuthRegisteredService(org.apereo.cas.support.oauth.services.OAuthRegisteredService) ProfileManager(org.pac4j.core.profile.ProfileManager) MessageDigestAlgorithms(org.apache.commons.codec.digest.MessageDigestAlgorithms) NumericDate(org.jose4j.jwt.NumericDate) OidcRegisteredService(org.apereo.cas.services.OidcRegisteredService) JwtClaims(org.jose4j.jwt.JwtClaims) J2EContext(org.pac4j.core.context.J2EContext) Optional(java.util.Optional) Principal(org.apereo.cas.authentication.principal.Principal) EncodingUtils(org.apereo.cas.util.EncodingUtils) UserProfile(org.pac4j.core.profile.UserProfile) WebUtils(org.apereo.cas.web.support.WebUtils) NumericDate(org.jose4j.jwt.NumericDate) JwtClaims(org.jose4j.jwt.JwtClaims) Authentication(org.apereo.cas.authentication.Authentication) Principal(org.apereo.cas.authentication.principal.Principal)

Example 5 with AccessToken

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);
}
Also used : ResponseEntity(org.springframework.http.ResponseEntity) LinkedMultiValueMap(org.springframework.util.LinkedMultiValueMap) AccessToken(org.apereo.cas.ticket.accesstoken.AccessToken) GetMapping(org.springframework.web.bind.annotation.GetMapping)

Aggregations

AccessToken (org.apereo.cas.ticket.accesstoken.AccessToken)12 Principal (org.apereo.cas.authentication.principal.Principal)6 MockHttpServletRequest (org.springframework.mock.web.MockHttpServletRequest)6 MockHttpServletResponse (org.springframework.mock.web.MockHttpServletResponse)6 OAuthRegisteredService (org.apereo.cas.support.oauth.services.OAuthRegisteredService)5 HashMap (java.util.HashMap)3 Test (org.junit.Test)3 CasProfile (org.pac4j.cas.profile.CasProfile)3 Authentication (org.apereo.cas.authentication.Authentication)2 OidcRegisteredService (org.apereo.cas.services.OidcRegisteredService)2 OAuth20ResponseTypes (org.apereo.cas.support.oauth.OAuth20ResponseTypes)2 RefreshToken (org.apereo.cas.ticket.refreshtoken.RefreshToken)2 J2EContext (org.pac4j.core.context.J2EContext)2 ProfileManager (org.pac4j.core.profile.ProfileManager)2 UserProfile (org.pac4j.core.profile.UserProfile)2 MockHttpSession (org.springframework.mock.web.MockHttpSession)2 ModelAndView (org.springframework.web.servlet.ModelAndView)2 View (org.springframework.web.servlet.View)2 RedirectView (org.springframework.web.servlet.view.RedirectView)2 ArrayList (java.util.ArrayList)1