Search in sources :

Example 31 with ClientDetails

use of org.springframework.security.oauth2.provider.ClientDetails in project ORCID-Source by ORCID.

the class OauthControllerBase method generateRequestInfoForm.

private RequestInfoForm generateRequestInfoForm(String clientId, String scopesString, String redirectUri, String responseType, String stateParam, String email, String orcid, String givenNames, String familyNames, String nonce, String maxAge) throws UnsupportedEncodingException {
    RequestInfoForm infoForm = new RequestInfoForm();
    // If the user is logged in
    String loggedUserOrcid = getEffectiveUserOrcid();
    if (!PojoUtil.isEmpty(loggedUserOrcid)) {
        infoForm.setUserOrcid(loggedUserOrcid);
        ProfileEntity profile = profileEntityCacheManager.retrieve(loggedUserOrcid);
        String creditName = "";
        RecordNameEntity recordName = profile.getRecordNameEntity();
        if (recordName != null) {
            if (!PojoUtil.isEmpty(profile.getRecordNameEntity().getCreditName())) {
                creditName = profile.getRecordNameEntity().getCreditName();
            } else {
                creditName = PojoUtil.isEmpty(profile.getRecordNameEntity().getGivenNames()) ? "" : profile.getRecordNameEntity().getGivenNames();
                creditName += PojoUtil.isEmpty(profile.getRecordNameEntity().getFamilyName()) ? "" : " " + profile.getRecordNameEntity().getFamilyName();
                creditName = creditName.trim();
            }
        }
        if (!PojoUtil.isEmpty(creditName)) {
            infoForm.setUserName(URLDecoder.decode(creditName, "UTF-8").trim());
        }
    }
    Set<ScopePathType> scopes = new HashSet<ScopePathType>();
    if (!PojoUtil.isEmpty(clientId) && !PojoUtil.isEmpty(scopesString)) {
        scopesString = URLDecoder.decode(scopesString, "UTF-8").trim();
        scopesString = scopesString.replaceAll(" +", " ");
        scopes = ScopePathType.getScopesFromSpaceSeparatedString(scopesString);
    } else {
        throw new InvalidRequestException("Unable to find parameters");
    }
    for (ScopePathType theScope : scopes) {
        ScopeInfoForm scopeInfoForm = new ScopeInfoForm();
        scopeInfoForm.setValue(theScope.value());
        scopeInfoForm.setName(theScope.name());
        try {
            scopeInfoForm.setDescription(getMessage(ScopePathType.class.getName() + '.' + theScope.name()));
            scopeInfoForm.setLongDescription(getMessage(ScopePathType.class.getName() + '.' + theScope.name() + ".longDesc"));
        } catch (NoSuchMessageException e) {
            LOGGER.warn("Unable to find key message for scope: " + theScope.name() + " " + theScope.value());
        }
        infoForm.getScopes().add(scopeInfoForm);
    }
    // Check if the client has persistent tokens enabled
    ClientDetailsEntity clientDetails = clientDetailsEntityCacheManager.retrieve(clientId);
    if (clientDetails.isPersistentTokensEnabled()) {
        infoForm.setClientHavePersistentTokens(true);
    }
    // If client details is ok, continue
    String clientName = clientDetails.getClientName() == null ? "" : clientDetails.getClientName();
    String clientEmailRequestReason = clientDetails.getEmailAccessReason() == null ? "" : clientDetails.getEmailAccessReason();
    String clientDescription = clientDetails.getClientDescription() == null ? "" : clientDetails.getClientDescription();
    String memberName = "";
    // If client type is null it means it is a public client
    if (ClientType.PUBLIC_CLIENT.equals(clientDetails.getClientType())) {
        memberName = PUBLIC_MEMBER_NAME;
    } else if (!PojoUtil.isEmpty(clientDetails.getGroupProfileId())) {
        ProfileEntity groupProfile = profileEntityCacheManager.retrieve(clientDetails.getGroupProfileId());
        if (groupProfile.getRecordNameEntity() != null) {
            memberName = groupProfile.getRecordNameEntity().getCreditName();
        }
    }
    // name, since it should be a SSO user
    if (StringUtils.isBlank(memberName)) {
        memberName = clientName;
    }
    if (!PojoUtil.isEmpty(email) || !PojoUtil.isEmpty(orcid)) {
        // Check if orcid exists, if so, show login screen
        if (!PojoUtil.isEmpty(orcid)) {
            orcid = orcid.trim();
            if (orcidProfileManager.exists(orcid)) {
                infoForm.setUserId(orcid);
            }
        } else {
            // Check if email exists, if so, show login screen
            if (!PojoUtil.isEmpty(email)) {
                email = email.trim();
                if (emailManager.emailExists(email)) {
                    infoForm.setUserId(email);
                }
            }
        }
    }
    infoForm.setUserEmail(email);
    if (PojoUtil.isEmpty(loggedUserOrcid))
        infoForm.setUserOrcid(orcid);
    infoForm.setUserGivenNames(givenNames);
    infoForm.setUserFamilyNames(familyNames);
    infoForm.setClientId(clientId);
    infoForm.setClientDescription(clientDescription);
    infoForm.setClientName(clientName);
    infoForm.setClientEmailRequestReason(clientEmailRequestReason);
    infoForm.setMemberName(memberName);
    infoForm.setRedirectUrl(redirectUri);
    infoForm.setStateParam(stateParam);
    infoForm.setResponseType(responseType);
    infoForm.setNonce(nonce);
    return infoForm;
}
Also used : ClientDetailsEntity(org.orcid.persistence.jpa.entities.ClientDetailsEntity) NoSuchMessageException(org.springframework.context.NoSuchMessageException) ScopePathType(org.orcid.jaxb.model.message.ScopePathType) RecordNameEntity(org.orcid.persistence.jpa.entities.RecordNameEntity) RequestInfoForm(org.orcid.pojo.ajaxForm.RequestInfoForm) InvalidRequestException(org.springframework.security.oauth2.common.exceptions.InvalidRequestException) ProfileEntity(org.orcid.persistence.jpa.entities.ProfileEntity) ScopeInfoForm(org.orcid.pojo.ajaxForm.ScopeInfoForm) HashSet(java.util.HashSet)

Example 32 with ClientDetails

use of org.springframework.security.oauth2.provider.ClientDetails in project ORCID-Source by ORCID.

the class OauthLoginController method loginGetHandler.

@RequestMapping(value = { "/oauth/signin", "/oauth/login" }, method = RequestMethod.GET)
public ModelAndView loginGetHandler(HttpServletRequest request, HttpServletResponse response, ModelAndView mav) throws UnsupportedEncodingException {
    String url = request.getQueryString();
    // default to Reg
    boolean showLogin = showLoginDefault;
    // Get and save the request information form
    RequestInfoForm requestInfoForm = generateRequestInfoForm(url);
    request.getSession().setAttribute(REQUEST_INFO_FORM, requestInfoForm);
    if (url.toLowerCase().contains("show_login=true"))
        showLogin = true;
    else if (url.toLowerCase().contains("show_login=false"))
        showLogin = false;
    // Check if userId is set so we should show the login screen
    if (!PojoUtil.isEmpty(requestInfoForm.getUserId())) {
        showLogin = true;
    }
    // Check that the client have the required permissions
    // Get client name
    ClientDetailsEntity clientDetails = clientDetailsEntityCacheManager.retrieve(requestInfoForm.getClientId());
    // validate client scopes
    try {
        authorizationEndpoint.validateScope(requestInfoForm.getScopesAsString(), clientDetails, requestInfoForm.getResponseType());
        orcidOAuth2RequestValidator.validateClientIsEnabled(clientDetails);
    } catch (InvalidScopeException | LockedException e) {
        String redirectUriWithParams = requestInfoForm.getRedirectUrl();
        if (e instanceof InvalidScopeException) {
            redirectUriWithParams += "?error=invalid_scope&error_description=" + e.getMessage();
        } else {
            redirectUriWithParams += "?error=client_locked&error_description=" + e.getMessage();
        }
        RedirectView rView = new RedirectView(redirectUriWithParams);
        ModelAndView error = new ModelAndView();
        error.setView(rView);
        return error;
    }
    // handle openID behaviour
    if (!PojoUtil.isEmpty(requestInfoForm.getScopesAsString()) && ScopePathType.getScopesFromSpaceSeparatedString(requestInfoForm.getScopesAsString()).contains(ScopePathType.OPENID)) {
        String prompt = request.getParameter(OrcidOauth2Constants.PROMPT);
        if (prompt != null && prompt.equals(OrcidOauth2Constants.PROMPT_NONE)) {
            String redirectUriWithParams = requestInfoForm.getRedirectUrl();
            redirectUriWithParams += "?error=login_required";
            RedirectView rView = new RedirectView(redirectUriWithParams);
            ModelAndView error = new ModelAndView();
            error.setView(rView);
            return error;
        }
    }
    mav.addObject("hideUserVoiceScript", true);
    mav.addObject("showLogin", String.valueOf(showLogin));
    mav.addObject("originalOauth2Process", true);
    mav.setViewName("oauth_login");
    return mav;
}
Also used : ClientDetailsEntity(org.orcid.persistence.jpa.entities.ClientDetailsEntity) LockedException(org.orcid.core.security.aop.LockedException) RedirectView(org.springframework.web.servlet.view.RedirectView) ModelAndView(org.springframework.web.servlet.ModelAndView) RequestInfoForm(org.orcid.pojo.ajaxForm.RequestInfoForm) InvalidScopeException(org.springframework.security.oauth2.common.exceptions.InvalidScopeException) RequestMapping(org.springframework.web.bind.annotation.RequestMapping)

Example 33 with ClientDetails

use of org.springframework.security.oauth2.provider.ClientDetails in project ORCID-Source by ORCID.

the class OrcidAuthorizationCodeServiceImpl method getDetailFromAuthorization.

private OrcidOauth2AuthoriziationCodeDetail getDetailFromAuthorization(String code, OAuth2Authentication authentication) {
    OAuth2Request oAuth2Request = authentication.getOAuth2Request();
    OrcidOauth2AuthoriziationCodeDetail detail = new OrcidOauth2AuthoriziationCodeDetail();
    Map<String, String> requestParameters = oAuth2Request.getRequestParameters();
    if (requestParameters != null && !requestParameters.isEmpty()) {
        String clientId = (String) requestParameters.get(CLIENT_ID);
        ClientDetailsEntity clientDetails = getClientDetails(clientId);
        if (clientDetails == null) {
            return null;
        }
        detail.setScopes(OAuth2Utils.parseParameterList((String) requestParameters.get(SCOPE)));
        detail.setState((String) requestParameters.get(STATE));
        detail.setRedirectUri((String) requestParameters.get(REDIRECT_URI));
        detail.setResponseType((String) requestParameters.get(RESPONSE_TYPE));
        detail.setClientDetailsEntity(clientDetails);
        // persist the openID params if present
        if (requestParameters.get(OrcidOauth2Constants.NONCE) != null)
            detail.setNonce((String) requestParameters.get(OrcidOauth2Constants.NONCE));
    }
    detail.setId(code);
    detail.setApproved(authentication.getOAuth2Request().isApproved());
    Authentication userAuthentication = authentication.getUserAuthentication();
    Object principal = userAuthentication.getDetails();
    ProfileEntity entity = null;
    if (principal instanceof OrcidProfileUserDetails) {
        OrcidProfileUserDetails userDetails = (OrcidProfileUserDetails) principal;
        String effectiveOrcid = userDetails.getOrcid();
        if (effectiveOrcid != null) {
            entity = profileEntityCacheManager.retrieve(effectiveOrcid);
        }
    }
    if (entity == null) {
        return null;
    }
    detail.setProfileEntity(entity);
    detail.setAuthenticated(userAuthentication.isAuthenticated());
    Set<String> authorities = getStringSetFromGrantedAuthorities(authentication.getAuthorities());
    detail.setAuthorities(authorities);
    Object authenticationDetails = userAuthentication.getDetails();
    if (authenticationDetails instanceof WebAuthenticationDetails) {
        detail.setSessionId(((WebAuthenticationDetails) authenticationDetails).getSessionId());
    }
    boolean isPersistentTokenEnabledByUser = false;
    // Set token version to persistent token
    // TODO: As of Jan 2015 all tokens will be new tokens, so, we will have to remove the token version code and
    // treat all tokens as new tokens
    detail.setVersion(Long.valueOf(OrcidOauth2Constants.PERSISTENT_TOKEN));
    if (requestParameters.containsKey(OrcidOauth2Constants.GRANT_PERSISTENT_TOKEN)) {
        String grantPersitentToken = (String) requestParameters.get(OrcidOauth2Constants.GRANT_PERSISTENT_TOKEN);
        if (Boolean.parseBoolean(grantPersitentToken)) {
            isPersistentTokenEnabledByUser = true;
        }
    }
    detail.setPersistent(isPersistentTokenEnabledByUser);
    return detail;
}
Also used : ClientDetailsEntity(org.orcid.persistence.jpa.entities.ClientDetailsEntity) OAuth2Request(org.springframework.security.oauth2.provider.OAuth2Request) OrcidOauth2AuthoriziationCodeDetail(org.orcid.persistence.jpa.entities.OrcidOauth2AuthoriziationCodeDetail) OrcidOauth2UserAuthentication(org.orcid.core.oauth.OrcidOauth2UserAuthentication) OAuth2Authentication(org.springframework.security.oauth2.provider.OAuth2Authentication) Authentication(org.springframework.security.core.Authentication) WebAuthenticationDetails(org.springframework.security.web.authentication.WebAuthenticationDetails) OrcidProfileUserDetails(org.orcid.core.oauth.OrcidProfileUserDetails) ProfileEntity(org.orcid.persistence.jpa.entities.ProfileEntity)

Example 34 with ClientDetails

use of org.springframework.security.oauth2.provider.ClientDetails in project ORCID-Source by ORCID.

the class OrcidRandomValueTokenServicesImpl method refreshAccessToken.

@Override
@Transactional
public OAuth2AccessToken refreshAccessToken(String refreshTokenValue, TokenRequest tokenRequest) throws AuthenticationException {
    String parentTokenValue = tokenRequest.getRequestParameters().get(OrcidOauth2Constants.AUTHORIZATION);
    String clientId = tokenRequest.getClientId();
    String scopes = tokenRequest.getRequestParameters().get(OAuth2Utils.SCOPE);
    Long expiresIn = tokenRequest.getRequestParameters().containsKey(OrcidOauth2Constants.EXPIRES_IN) ? Long.valueOf(tokenRequest.getRequestParameters().get(OrcidOauth2Constants.EXPIRES_IN)) : 0L;
    Boolean revokeOld = tokenRequest.getRequestParameters().containsKey(OrcidOauth2Constants.REVOKE_OLD) ? Boolean.valueOf(tokenRequest.getRequestParameters().get(OrcidOauth2Constants.REVOKE_OLD)) : true;
    // Check if the refresh token is enabled
    if (!customSupportRefreshToken) {
        throw new InvalidGrantException("Invalid refresh token: " + refreshTokenValue);
    }
    // Check if the client support refresh token
    ClientDetailsEntity clientDetails = clientDetailsEntityCacheManager.retrieve(clientId);
    if (!clientDetails.getAuthorizedGrantTypes().contains(OrcidOauth2Constants.REFRESH_TOKEN)) {
        throw new InvalidGrantException("Client " + clientId + " doesnt have refresh token enabled");
    }
    OrcidOauth2TokenDetail parentToken = orcidOauth2TokenDetailDao.findByRefreshTokenValue(refreshTokenValue);
    ProfileEntity profileEntity = new ProfileEntity(parentToken.getProfile().getId());
    OrcidOauth2TokenDetail newToken = new OrcidOauth2TokenDetail();
    newToken.setApproved(true);
    newToken.setClientDetailsId(clientId);
    newToken.setDateCreated(new Date());
    newToken.setLastModified(new Date());
    newToken.setPersistent(parentToken.isPersistent());
    newToken.setProfile(profileEntity);
    newToken.setRedirectUri(parentToken.getRedirectUri());
    newToken.setRefreshTokenValue(UUID.randomUUID().toString());
    newToken.setResourceId(parentToken.getResourceId());
    newToken.setResponseType(parentToken.getResponseType());
    newToken.setState(parentToken.getState());
    newToken.setTokenDisabled(false);
    if (expiresIn <= 0) {
        // If expiresIn is 0 or less, set the parent token
        newToken.setTokenExpiration(parentToken.getTokenExpiration());
    } else {
        // Assumes expireIn already contains the real expired time expressed in millis
        newToken.setTokenExpiration(new Date(expiresIn));
    }
    newToken.setTokenType(parentToken.getTokenType());
    newToken.setTokenValue(UUID.randomUUID().toString());
    newToken.setVersion(parentToken.getVersion());
    if (PojoUtil.isEmpty(scopes)) {
        newToken.setScope(parentToken.getScope());
    } else {
        newToken.setScope(scopes);
    }
    // Generate an authentication object to be able to generate the authentication key
    Set<String> scopesSet = OAuth2Utils.parseParameterList(newToken.getScope());
    AuthorizationRequest request = new AuthorizationRequest(clientId, scopesSet);
    request.setApproved(true);
    Authentication authentication = new OrcidOauth2UserAuthentication(profileEntity, true);
    OrcidOAuth2Authentication orcidAuthentication = new OrcidOAuth2Authentication(request, authentication, newToken.getTokenValue());
    newToken.setAuthenticationKey(authenticationKeyGenerator.extractKey(orcidAuthentication));
    // Store the new token and return it
    orcidOauth2TokenDetailDao.persist(newToken);
    // Revoke the old token when required
    if (revokeOld) {
        orcidOauth2TokenDetailDao.disableAccessToken(parentTokenValue);
    }
    // Save the changes
    orcidOauth2TokenDetailDao.flush();
    // and return it
    return toOAuth2AccessToken(newToken);
}
Also used : ClientDetailsEntity(org.orcid.persistence.jpa.entities.ClientDetailsEntity) AuthorizationRequest(org.springframework.security.oauth2.provider.AuthorizationRequest) OrcidOAuth2Authentication(org.orcid.core.oauth.OrcidOAuth2Authentication) InvalidGrantException(org.springframework.security.oauth2.common.exceptions.InvalidGrantException) ProfileEntity(org.orcid.persistence.jpa.entities.ProfileEntity) Date(java.util.Date) OrcidOauth2UserAuthentication(org.orcid.core.oauth.OrcidOauth2UserAuthentication) OAuth2Authentication(org.springframework.security.oauth2.provider.OAuth2Authentication) OrcidOAuth2Authentication(org.orcid.core.oauth.OrcidOAuth2Authentication) Authentication(org.springframework.security.core.Authentication) OrcidOauth2UserAuthentication(org.orcid.core.oauth.OrcidOauth2UserAuthentication) OrcidOauth2TokenDetail(org.orcid.persistence.jpa.entities.OrcidOauth2TokenDetail) Transactional(org.springframework.transaction.annotation.Transactional)

Example 35 with ClientDetails

use of org.springframework.security.oauth2.provider.ClientDetails in project ORCID-Source by ORCID.

the class OrcidRefreshTokenChecker method validateRequest.

public void validateRequest(String grantType, TokenRequest tokenRequest, Long requestTimeInMillis) {
    String authorization = tokenRequest.getRequestParameters().get(OrcidOauth2Constants.AUTHORIZATION);
    String clientId = tokenRequest.getClientId();
    String scopes = tokenRequest.getRequestParameters().get(OAuth2Utils.SCOPE);
    Long expireIn = tokenRequest.getRequestParameters().containsKey(OrcidOauth2Constants.EXPIRES_IN) ? Long.valueOf(tokenRequest.getRequestParameters().get(OrcidOauth2Constants.EXPIRES_IN)) : 0L;
    String refreshToken = tokenRequest.getRequestParameters().get(OrcidOauth2Constants.REFRESH_TOKEN);
    OrcidOauth2TokenDetail token = null;
    try {
        token = orcidOauth2TokenDetailDao.findByRefreshTokenValue(refreshToken);
    } catch (NoResultException e) {
        throw new InvalidTokenException("Unable to find refresh token", e);
    }
    // Verify the token belongs to this client
    if (!clientId.equals(token.getClientDetailsId())) {
        throw new IllegalArgumentException("This token does not belong to the given client");
    }
    // Verify client is enabled
    ClientDetailsEntity clientDetails = clientDetailsEntityCacheManager.retrieve(clientId);
    orcidOAuth2RequestValidator.validateClientIsEnabled(clientDetails);
    // Verify the token is not expired
    if (token.getTokenExpiration() != null) {
        if (token.getTokenExpiration().before(new Date())) {
            throw new InvalidTokenException("Access token expired: " + authorization);
        }
    }
    // Verify access token and refresh token are linked
    if (!refreshToken.equals(token.getRefreshTokenValue())) {
        throw new InvalidTokenException("Token and refresh token does not match");
    }
    // Verify the token is not disabled
    if (token.getTokenDisabled() != null && token.getTokenDisabled()) {
        throw new InvalidTokenException("Parent token is disabled");
    }
    // Verify scopes are not wider than the token scopes
    if (PojoUtil.isEmpty(scopes)) {
        scopes = token.getScope();
    } else {
        Set<ScopePathType> requiredScopes = ScopePathType.getScopesFromSpaceSeparatedString(scopes);
        Set<ScopePathType> simpleTokenScopes = ScopePathType.getScopesFromSpaceSeparatedString(token.getScope());
        // This collection contains all tokens that should be allowed given
        // the scopes that the parent token contains
        Set<ScopePathType> combinedTokenScopes = new HashSet<ScopePathType>();
        for (ScopePathType scope : simpleTokenScopes) {
            combinedTokenScopes.addAll(scope.combined());
        }
        // combinedTokenScopes
        for (ScopePathType scope : requiredScopes) {
            if (!combinedTokenScopes.contains(scope)) {
                throw new InvalidScopeException("The given scope '" + scope.value() + "' is not allowed for the parent token");
            }
        }
    }
    // Validate the expiration for the new token is no later than the parent
    // token expiration.
    long parentTokenExpiration = token.getTokenExpiration() == null ? System.currentTimeMillis() : token.getTokenExpiration().getTime();
    if (expireIn > parentTokenExpiration) {
        throw new IllegalArgumentException("Token expiration can't be after " + token.getTokenExpiration());
    }
}
Also used : InvalidTokenException(org.springframework.security.oauth2.common.exceptions.InvalidTokenException) ClientDetailsEntity(org.orcid.persistence.jpa.entities.ClientDetailsEntity) NoResultException(javax.persistence.NoResultException) Date(java.util.Date) ScopePathType(org.orcid.jaxb.model.message.ScopePathType) InvalidScopeException(org.springframework.security.oauth2.common.exceptions.InvalidScopeException) OrcidOauth2TokenDetail(org.orcid.persistence.jpa.entities.OrcidOauth2TokenDetail) HashSet(java.util.HashSet)

Aggregations

ClientDetails (org.springframework.security.oauth2.provider.ClientDetails)44 Test (org.junit.Test)36 BaseClientDetails (org.springframework.security.oauth2.provider.client.BaseClientDetails)30 OAuth2Authentication (org.springframework.security.oauth2.provider.OAuth2Authentication)27 Authentication (org.springframework.security.core.Authentication)21 ClientDetailsEntity (org.orcid.persistence.jpa.entities.ClientDetailsEntity)20 OAuth2AccessToken (org.springframework.security.oauth2.common.OAuth2AccessToken)19 OAuth2Request (org.springframework.security.oauth2.provider.OAuth2Request)19 Date (java.util.Date)13 HashMap (java.util.HashMap)12 TokenRequest (org.springframework.security.oauth2.provider.TokenRequest)8 ProfileEntity (org.orcid.persistence.jpa.entities.ProfileEntity)7 ClientDetailsService (org.springframework.security.oauth2.provider.ClientDetailsService)7 DBUnitTest (org.orcid.test.DBUnitTest)6 AnnotationConfigServletWebServerApplicationContext (org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext)6 DefaultOAuth2AccessToken (org.springframework.security.oauth2.common.DefaultOAuth2AccessToken)6 OAuth2Exception (org.springframework.security.oauth2.common.exceptions.OAuth2Exception)6 AuthorizationRequest (org.springframework.security.oauth2.provider.AuthorizationRequest)6 OrcidOauth2ClientAuthentication (org.orcid.core.oauth.OrcidOauth2ClientAuthentication)5 InvalidClientException (org.springframework.security.oauth2.common.exceptions.InvalidClientException)5