All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.github.microcks.security.OAuth2AuthorizedClientProvider Maven / Gradle / Ivy

The newest version!
/*
 * Copyright The Microcks Authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *  http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package io.github.microcks.security;

import io.github.microcks.domain.OAuth2AuthorizedClient;
import io.github.microcks.domain.OAuth2ClientContext;
import io.github.microcks.domain.OAuth2GrantType;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.oauth2.client.endpoint.DefaultClientCredentialsTokenResponseClient;
import org.springframework.security.oauth2.client.endpoint.DefaultPasswordTokenResponseClient;
import org.springframework.security.oauth2.client.endpoint.DefaultRefreshTokenTokenResponseClient;
import org.springframework.security.oauth2.client.endpoint.OAuth2ClientCredentialsGrantRequest;
import org.springframework.security.oauth2.client.endpoint.OAuth2PasswordGrantRequest;
import org.springframework.security.oauth2.client.endpoint.OAuth2RefreshTokenGrantRequest;
import org.springframework.security.oauth2.client.registration.ClientRegistration;
import org.springframework.security.oauth2.core.AuthorizationGrantType;
import org.springframework.security.oauth2.core.OAuth2AccessToken;
import org.springframework.security.oauth2.core.OAuth2AuthorizationException;
import org.springframework.security.oauth2.core.OAuth2RefreshToken;
import org.springframework.security.oauth2.core.endpoint.OAuth2AccessTokenResponse;

import java.util.Arrays;

/**
 * Process OAuth2 authorization flow and tries to authorize from a client context.
 * @author laurent
 */
public class OAuth2AuthorizedClientProvider {

   /** A simple logger for diagnostic messages. */
   private static Logger log = LoggerFactory.getLogger(OAuth2AuthorizedClientProvider.class);

   /**
    * Realize OAuth2 authorization trying to get an access token from the given OAuth2 client context. Token as well as
    * traceability information are then transferred as a result in the OAuth2AuthorizedClient
    * @param oAuth2ClientContext The client context for OAuth2 authorization flow
    * @return An authorized client with traceability elements being principal and access token.
    * @throws AuthorizationException
    */
   public OAuth2AuthorizedClient authorize(OAuth2ClientContext oAuth2ClientContext) throws AuthorizationException {

      OAuth2AccessToken accessToken = null;
      try {
         switch (oAuth2ClientContext.getGrantType()) {
            case PASSWORD -> accessToken = getResourceOwnerPasswordAccessToken(oAuth2ClientContext);
            case CLIENT_CREDENTIALS -> accessToken = getClientCredentialsAccessToken(oAuth2ClientContext);
            case REFRESH_TOKEN -> accessToken = getRefreshTokenAccessToken(oAuth2ClientContext);
         }
      } catch (OAuth2AuthorizationException oAuth2AuthorizationException) {
         log.error("Error during {} grant type fetching", oAuth2ClientContext.getGrantType(),
               oAuth2AuthorizationException);
         throw new AuthorizationException("Error during " + oAuth2ClientContext.getGrantType() + " grant type fetching",
               oAuth2AuthorizationException);
      }

      String principalName = oAuth2ClientContext.getClientId();
      if (oAuth2ClientContext.getGrantType() == OAuth2GrantType.PASSWORD) {
         principalName = oAuth2ClientContext.getUsername();
      }

      return new OAuth2AuthorizedClient(oAuth2ClientContext.getGrantType(), principalName,
            oAuth2ClientContext.getTokenUri(), String.join(" ", accessToken.getScopes()), accessToken.getTokenValue());
   }

   private OAuth2AccessToken getResourceOwnerPasswordAccessToken(OAuth2ClientContext oAuth2ClientContext) {
      // Build a ClientRegistration with PASSWORD grant type.
      ClientRegistration registration = initializeClientRegistration(oAuth2ClientContext)
            .authorizationGrantType(AuthorizationGrantType.PASSWORD).build();

      DefaultPasswordTokenResponseClient client = new DefaultPasswordTokenResponseClient();
      OAuth2PasswordGrantRequest request = new OAuth2PasswordGrantRequest(registration,
            oAuth2ClientContext.getUsername(), oAuth2ClientContext.getPassword());
      OAuth2AccessTokenResponse response = client.getTokenResponse(request);

      return response.getAccessToken();
   }

   private OAuth2AccessToken getClientCredentialsAccessToken(OAuth2ClientContext oAuth2ClientContext) {
      // Build a ClientRegistration with CLIENT_CREDENTIALS grant type.
      ClientRegistration registration = initializeClientRegistration(oAuth2ClientContext)
            .authorizationGrantType(AuthorizationGrantType.CLIENT_CREDENTIALS).build();

      DefaultClientCredentialsTokenResponseClient client = new DefaultClientCredentialsTokenResponseClient();
      OAuth2ClientCredentialsGrantRequest request = new OAuth2ClientCredentialsGrantRequest(registration);
      OAuth2AccessTokenResponse response = client.getTokenResponse(request);

      return response.getAccessToken();
   }

   private OAuth2AccessToken getRefreshTokenAccessToken(OAuth2ClientContext oAuth2ClientContext) {
      // Build a ClientRegistration with REFRESH_TOKEN grant type.
      ClientRegistration registration = initializeClientRegistration(oAuth2ClientContext)
            .authorizationGrantType(AuthorizationGrantType.REFRESH_TOKEN).build();

      DefaultRefreshTokenTokenResponseClient clientRT = new DefaultRefreshTokenTokenResponseClient();
      OAuth2RefreshTokenGrantRequest requestRT = new OAuth2RefreshTokenGrantRequest(registration,
            new OAuth2AccessToken(OAuth2AccessToken.TokenType.BEARER, "fake-one", null, null),
            new OAuth2RefreshToken(oAuth2ClientContext.getRefreshToken(), null));
      OAuth2AccessTokenResponse response = clientRT.getTokenResponse(requestRT);

      return response.getAccessToken();
   }

   private ClientRegistration.Builder initializeClientRegistration(OAuth2ClientContext oAuth2ClientContext) {
      ClientRegistration.Builder builder = ClientRegistration.withRegistrationId("microcks-test-idp")
            .clientId(oAuth2ClientContext.getClientId()).clientSecret(oAuth2ClientContext.getClientSecret())
            .tokenUri(oAuth2ClientContext.getTokenUri());

      if (oAuth2ClientContext.getScopes() != null) {
         String[] scopes = (oAuth2ClientContext.getScopes() + " openid").split(" ");
         builder.scope(Arrays.asList(scopes));
      } else {
         builder.scope("openid");
      }

      return builder;
   }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy