/**
   * Create an authorization request applying various UAA rules to the authorizationParameters and
   * the registered client details.
   *
   * <ul>
   *   <li>For client_credentials grants, the default scopes are the client's granted authorities
   *   <li>For other grant types the default scopes are the registered scopes in the client details
   *   <li>Only scopes in those lists are valid, otherwise there is an exception
   *   <li>If the scopes contain separators then resource ids are extracted as the scope value up to
   *       the last index of the separator
   *   <li>Some scopes can be hard-wired to resource ids (like the open id connect values), in which
   *       case the separator is ignored
   * </ul>
   *
   * @see
   *     org.springframework.security.oauth2.provider.AuthorizationRequestFactory#createAuthorizationRequest(java.util.Map,
   *     java.lang.String, java.lang.String, java.util.Set)
   */
  @Override
  public AuthorizationRequest createAuthorizationRequest(
      Map<String, String> authorizationParameters) {

    String clientId = authorizationParameters.get("client_id");
    BaseClientDetails clientDetails =
        new BaseClientDetails(clientDetailsService.loadClientByClientId(clientId));

    Set<String> scopes = OAuth2Utils.parseParameterList(authorizationParameters.get("scope"));
    String grantType = authorizationParameters.get("grant_type");
    if ((scopes == null || scopes.isEmpty())) {
      if ("client_credentials".equals(grantType)) {
        // The client authorities should be a list of scopes
        scopes = AuthorityUtils.authorityListToSet(clientDetails.getAuthorities());
      } else {
        // The default for a user token is the scopes registered with
        // the client
        scopes = clientDetails.getScope();
      }
    }

    Set<String> scopesFromExternalAuthorities = null;
    if (!"client_credentials".equals(grantType) && securityContextAccessor.isUser()) {
      scopes = checkUserScopes(scopes, securityContextAccessor.getAuthorities(), clientDetails);

      // TODO: will the grantType ever contain client_credentials or
      // authorization_code
      // External Authorities are things like LDAP groups that will be
      // mapped to Oauth scopes
      // Add those scopes to the request. These scopes will not be
      // validated against the scopes
      // registered to a client.
      // These scopes also do not need approval. The fact that they are
      // already in an external
      // group communicates user approval. Denying approval does not mean
      // much
      scopesFromExternalAuthorities =
          findScopesFromAuthorities(authorizationParameters.get("authorities"));
    }

    Set<String> resourceIds = getResourceIds(clientDetails, scopes);
    clientDetails.setResourceIds(resourceIds);
    DefaultAuthorizationRequest request = new DefaultAuthorizationRequest(authorizationParameters);
    if (!scopes.isEmpty()) {
      request.setScope(scopes);
    }
    if (scopesFromExternalAuthorities != null) {
      Map<String, String> existingAuthorizationParameters = new LinkedHashMap<String, String>();
      existingAuthorizationParameters.putAll(request.getAuthorizationParameters());
      existingAuthorizationParameters.put(
          "external_scopes", OAuth2Utils.formatParameterList(scopesFromExternalAuthorities));
      request.setAuthorizationParameters(existingAuthorizationParameters);
    }

    request.addClientDetails(clientDetails);

    return request;
  }
 /**
  * @param formParams
  * @return
  */
 @POST
 @Path(OAUTH_TOKEN)
 @Produces(value = {MediaType.APPLICATION_JSON})
 @Consumes(MediaType.APPLICATION_FORM_URLENCODED)
 public Response obtainOauth2TokenPost(
     @FormParam("grant_type") String grantType, MultivaluedMap<String, String> formParams) {
   String clientId = formParams.getFirst("client_id");
   String clientSecret = formParams.getFirst("client_secret");
   String code = formParams.getFirst("code");
   String state = formParams.getFirst("state");
   String redirectUri = formParams.getFirst("redirect_uri");
   String resourceId = formParams.getFirst("resource_id");
   String refreshToken = formParams.getFirst("refresh_token");
   String scopeList = formParams.getFirst("scope");
   Set<String> scopes = new HashSet<String>();
   if (StringUtils.isNotEmpty(scopeList)) {
     scopes = OAuth2Utils.parseParameterList(scopeList);
   }
   return orcidClientCredentialEndPointDelegator.obtainOauth2Token(
       clientId,
       clientSecret,
       refreshToken,
       grantType,
       code,
       scopes,
       state,
       redirectUri,
       resourceId);
 }
  @Override
  public AuthorizationRequest createAuthorizationRequest(Map<String, String> parameters) {

    String clientId = parameters.get("client_id");
    if (clientId == null) {
      throw new InvalidClientException("A client id must be provided");
    }
    ClientDetails client = clientDetailsService.loadClientByClientId(clientId);

    String requestNonce = parameters.get("nonce");

    // Only process if the user is authenticated. If the user is not authenticated yet, this
    // code will be called a second time once the user is redirected from the login page back
    // to the auth endpoint.
    Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();

    if (requestNonce != null && principal != null && principal instanceof User) {

      // Check request nonce for reuse
      Collection<Nonce> clientNonces = nonceService.getByClientId(client.getClientId());
      for (Nonce nonce : clientNonces) {
        String nonceVal = nonce.getValue();
        if (nonceVal.equals(requestNonce)) {
          throw new NonceReuseException(client.getClientId(), nonce);
        }
      }

      // Store nonce
      Nonce nonce = new Nonce();
      nonce.setClientId(client.getClientId());
      nonce.setValue(requestNonce);
      DateTime now = new DateTime(new Date());
      nonce.setUseDate(now.toDate());
      DateTime expDate = now.plus(nonceStorageDuration);
      Date expirationJdkDate = expDate.toDate();
      nonce.setExpireDate(expirationJdkDate);

      nonceService.save(nonce);
    }

    Set<String> scopes = OAuth2Utils.parseParameterList(parameters.get("scope"));
    if ((scopes == null || scopes.isEmpty())) {
      // TODO: do we want to allow default scoping at all?
      // If no scopes are specified in the incoming data, it is possible to default to the client's
      // registered scopes, but minus the "openid" scope. OpenID Connect requests MUST have the
      // "openid" scope.
      Set<String> clientScopes = client.getScope();
      if (clientScopes.contains("openid")) {
        clientScopes.remove("openid");
      }
      scopes = clientScopes;
    }
    DefaultAuthorizationRequest request =
        new DefaultAuthorizationRequest(
            parameters, Collections.<String, String>emptyMap(), clientId, scopes);
    request.addClientDetails(client);
    return request;
  }
 @Override
 public void validateParameters(Map<String, String> parameters, ClientDetails clientDetails) {
   if (parameters.containsKey("scope")) {
     if (clientDetails.isScoped()) {
       Set<String> validScope = clientDetails.getScope();
       for (String scope : OAuth2Utils.parseParameterList(parameters.get("scope"))) {
         if (!validScope.contains(scope)) {
           throw new InvalidScopeException("Invalid scope: " + scope, validScope);
         }
       }
     }
   }
 }
  private String appendAccessToken(
      AuthorizationRequest authorizationRequest, OAuth2AccessToken accessToken) {

    Map<String, Object> vars = new LinkedHashMap<String, Object>();
    Map<String, String> keys = new HashMap<String, String>();

    if (accessToken == null) {
      throw new InvalidRequestException("An implicit grant could not be made");
    }

    vars.put("access_token", accessToken.getValue());
    vars.put("token_type", accessToken.getTokenType());
    String state = authorizationRequest.getState();

    if (state != null) {
      vars.put("state", state);
    }
    Date expiration = accessToken.getExpiration();
    if (expiration != null) {
      long expires_in = (expiration.getTime() - System.currentTimeMillis()) / 1000;
      vars.put("expires_in", expires_in);
    }
    String originalScope = authorizationRequest.getRequestParameters().get(OAuth2Utils.SCOPE);
    if (originalScope == null
        || !OAuth2Utils.parseParameterList(originalScope).equals(accessToken.getScope())) {
      vars.put("scope", OAuth2Utils.formatParameterList(accessToken.getScope()));
    }
    Map<String, Object> additionalInformation = accessToken.getAdditionalInformation();
    for (String key : additionalInformation.keySet()) {
      Object value = additionalInformation.get(key);
      if (value != null) {
        keys.put("extra_" + key, key);
        vars.put("extra_" + key, value);
      }
    }
    // Do not include the refresh token (even if there is one)
    return append(authorizationRequest.getRedirectUri(), vars, keys, true);
  }
  /* (non-Javadoc)
   * @see org.mitre.oauth2.introspectingfilter.IntrospectionAuthorityGranter#getAuthorities(net.minidev.json.JSONObject)
   */
  @Override
  public List<GrantedAuthority> getAuthorities(JsonObject introspectionResponse) {
    List<GrantedAuthority> auth = new ArrayList<>(getAuthorities());

    if (introspectionResponse.has("scope")
        && introspectionResponse.get("scope").isJsonPrimitive()) {
      String scopeString = introspectionResponse.get("scope").getAsString();
      Set<String> scopes = OAuth2Utils.parseParameterList(scopeString);
      for (String scope : scopes) {
        auth.add(new SimpleGrantedAuthority("OAUTH_SCOPE_" + scope));
      }
    }

    return auth;
  }
 /**
  * Apply UAA rules to validate the requested scope. For client credentials grants the valid scopes
  * are actually in the authorities of the client.
  *
  * @see
  *     org.springframework.security.oauth2.provider.endpoint.ParametersValidator#validateParameters(java.util.Map,
  *     org.springframework.security.oauth2.provider.ClientDetails)
  */
 @Override
 public void validateParameters(Map<String, String> parameters, ClientDetails clientDetails) {
   if (parameters.containsKey("scope")) {
     Set<String> validScope = clientDetails.getScope();
     if ("client_credentials".equals(parameters.get("grant_type"))) {
       validScope = AuthorityUtils.authorityListToSet(clientDetails.getAuthorities());
     }
     for (String scope : OAuth2Utils.parseParameterList(parameters.get("scope"))) {
       if (!validScope.contains(scope)) {
         throw new InvalidScopeException(
             "Invalid scope: "
                 + scope
                 + ". Did you know that you can get default scopes by simply sending no value?",
             validScope);
       }
     }
   }
 }
 private Collection<String> getScope(HttpServletRequest request) {
   return OAuth2Utils.parseParameterList(request.getParameter("scope"));
 }