package org.onap.so.adapters.vnfmadapter;
import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
import java.util.ArrayList;
import java.util.Collection;
-import org.onap.so.adapters.vnfmadapter.extclients.vnfm.lcn.JSON;
+import org.onap.so.adapters.vnfmadapter.oauth.OAuth2AccessTokenAdapter;
import org.springframework.boot.autoconfigure.http.HttpMessageConverters;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.json.GsonHttpMessageConverter;
+import org.springframework.security.oauth2.common.OAuth2AccessToken;
/**
* Configures message converter
@Bean
public HttpMessageConverters customConverters() {
final Collection<HttpMessageConverter<?>> messageConverters = new ArrayList<>();
- final Gson gson = new JSON().getGson();
+ final Gson gson = new GsonBuilder()
+ .registerTypeHierarchyAdapter(OAuth2AccessToken.class, new OAuth2AccessTokenAdapter()).create();
final GsonHttpMessageConverter gsonHttpMessageConverter = new GsonHttpMessageConverter(gson);
messageConverters.add(gsonHttpMessageConverter);
return new HttpMessageConverters(true, messageConverters);
@Override
protected void configure(final HttpSecurity http) throws Exception {
- http.csrf().disable().authorizeRequests()
- .antMatchers("/manage/health", "/manage/info", Constants.BASE_URL + "/lcn/**",
- Constants.BASE_URL + "/grants/**")
- .permitAll().antMatchers("/**").hasAnyRole(StringUtils.collectionToDelimitedString(getRoles(), ","))
- .and().httpBasic();
+ http.csrf().disable().authorizeRequests().antMatchers("/manage/health", "/manage/info").permitAll()
+ .antMatchers("/**").hasAnyRole(StringUtils.collectionToDelimitedString(getRoles(), ",")).and()
+ .httpBasic();
}
@Override
import org.onap.so.adapters.vnfmadapter.extclients.vnfm.model.SubscriptionsAuthentication;
import org.onap.so.adapters.vnfmadapter.extclients.vnfm.model.SubscriptionsAuthentication.AuthTypeEnum;
import org.onap.so.adapters.vnfmadapter.extclients.vnfm.model.SubscriptionsAuthenticationParamsBasic;
+import org.onap.so.adapters.vnfmadapter.extclients.vnfm.model.SubscriptionsAuthenticationParamsOauth2ClientCredentials;
import org.onap.so.adapters.vnfmadapter.extclients.vnfm.model.SubscriptionsFilter;
import org.onap.so.adapters.vnfmadapter.extclients.vnfm.model.SubscriptionsFilter.NotificationTypesEnum;
import org.onap.so.adapters.vnfmadapter.extclients.vnfm.model.SubscriptionsFilterVnfInstanceSubscriptionFilter;
}
private SubscriptionsAuthentication getSubscriptionsAuthentication() throws GeneralSecurityException {
- final SubscriptionsAuthenticationParamsBasic basicAuthParams = new SubscriptionsAuthenticationParamsBasic();
+ final SubscriptionsAuthentication authentication = new SubscriptionsAuthentication();
+
final String[] decrypedAuth = CryptoUtils.decrypt(vnfmAdapterAuth, msoEncryptionKey).split(":");
+
+ SubscriptionsAuthenticationParamsOauth2ClientCredentials oauthParams =
+ new SubscriptionsAuthenticationParamsOauth2ClientCredentials();
+ oauthParams.setTokenEndpoint(vnfmAdapterEndoint + "/oauth/token");
+ oauthParams.clientId(decrypedAuth[0]);
+ oauthParams.setClientPassword(decrypedAuth[1]);
+ authentication.addAuthTypeItem(AuthTypeEnum.OAUTH2_CLIENT_CREDENTIALS);
+ authentication.paramsOauth2ClientCredentials(oauthParams);
+
+ final SubscriptionsAuthenticationParamsBasic basicAuthParams = new SubscriptionsAuthenticationParamsBasic();
basicAuthParams.setUserName(decrypedAuth[0]);
basicAuthParams.setPassword(decrypedAuth[1]);
-
- final SubscriptionsAuthentication authentication = new SubscriptionsAuthentication();
authentication.addAuthTypeItem(AuthTypeEnum.BASIC);
authentication.paramsBasic(basicAuthParams);
return authentication;
--- /dev/null
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2019 Nordix Foundation.
+ * ================================================================================
+ * 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.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.so.adapters.vnfmadapter.oauth;
+
+import org.onap.so.utils.CryptoUtils;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
+import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer;
+import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter;
+import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;
+
+@Configuration
+@EnableAuthorizationServer
+/**
+ * Configures the authorization server for oauth token based authentication.
+ */
+public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {
+
+ private static final int ONE_DAY = 60 * 60 * 24;
+
+ @Value("${vnfmadapter.auth:E39823AAB2739CC654C4E92B52C05BC34149342D0A46451B00CA508C8EDC62242CE4E9DA9445D3C01A3F13}")
+ private String vnfmAdapterAuth;
+
+ @Value("${mso.key}")
+ private String msoEncryptionKey;
+
+ @Override
+ public void configure(final ClientDetailsServiceConfigurer clients) throws Exception {
+ final String[] decrypedAuth = CryptoUtils.decrypt(vnfmAdapterAuth, msoEncryptionKey).split(":");
+ BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
+ clients.inMemory().withClient(decrypedAuth[0]).secret(passwordEncoder.encode(decrypedAuth[1]))
+ .authorizedGrantTypes("client_credentials").scopes("write").accessTokenValiditySeconds(ONE_DAY)
+ .refreshTokenValiditySeconds(ONE_DAY);
+ }
+
+}
--- /dev/null
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2019 Nordix Foundation.
+ * ================================================================================
+ * 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.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.so.adapters.vnfmadapter.oauth;
+
+import com.google.gson.JsonArray;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonSerializationContext;
+import com.google.gson.JsonSerializer;
+import java.lang.reflect.Type;
+import org.springframework.security.oauth2.common.OAuth2AccessToken;
+
+public class OAuth2AccessTokenAdapter implements JsonSerializer<OAuth2AccessToken> {
+
+ @Override
+ public JsonElement serialize(final OAuth2AccessToken src, final Type typeOfSrc,
+ final JsonSerializationContext context) {
+ final JsonObject obj = new JsonObject();
+ obj.addProperty(OAuth2AccessToken.ACCESS_TOKEN, src.getValue());
+ obj.addProperty(OAuth2AccessToken.TOKEN_TYPE, src.getTokenType());
+ if (src.getRefreshToken() != null) {
+ obj.addProperty(OAuth2AccessToken.REFRESH_TOKEN, src.getRefreshToken().getValue());
+ }
+ obj.addProperty(OAuth2AccessToken.EXPIRES_IN, src.getExpiresIn());
+ final JsonArray scopeObj = new JsonArray();
+ for (final String scope : src.getScope()) {
+ scopeObj.add(scope);
+ }
+ obj.add(OAuth2AccessToken.SCOPE, scopeObj);
+
+ return obj;
+ }
+}
--- /dev/null
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2019 Nordix Foundation.
+ * ================================================================================
+ * 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.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.so.adapters.vnfmadapter.oauth;
+
+import javax.servlet.http.HttpServletRequest;
+import org.onap.so.adapters.vnfmadapter.Constants;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.security.config.annotation.web.builders.HttpSecurity;
+import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
+import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter;
+import org.springframework.security.web.util.matcher.RequestMatcher;
+
+@Configuration
+@EnableResourceServer
+/**
+ * Enforces oauth token based authentication when a token is provided in the request.
+ */
+public class OAuth2ResourceServer extends ResourceServerConfigurerAdapter {
+
+ @Override
+ public void configure(final HttpSecurity http) throws Exception {
+ http.requestMatcher(new OAuth2ResourceServerRequestMatcher()).authorizeRequests()
+ .antMatchers(Constants.BASE_URL + "/grants/**", Constants.BASE_URL + "/lcn/**").authenticated();
+ }
+
+ private static class OAuth2ResourceServerRequestMatcher implements RequestMatcher {
+ @Override
+ public boolean matches(HttpServletRequest request) {
+ String auth = request.getHeader("Authorization");
+ String uri = request.getRequestURI();
+ return (auth != null && auth.startsWith("Bearer") && (uri.contains("/grants") || uri.contains("/lcn/")));
+ }
+ }
+}
setUpVimInMockAai();
final String expectedsubscriptionRequest =
- "{\"filter\":{\"vnfInstanceSubscriptionFilter\":{\"vnfInstanceIds\":[\"vnfId\"]},\"notificationTypes\":[\"VnfLcmOperationOccurrenceNotification\"]},\"callbackUri\":\"https://so-vnfm-adapter.onap:30406/so/vnfm-adapter/v1/lcn/VnfLcmOperationOccurrenceNotification\",\"authentication\":{\"authType\":[\"BASIC\"],\"paramsBasic\":{\"userName\":\"vnfm\",\"password\":\"password1$\"}}}";
+ "{\"filter\":{\"vnfInstanceSubscriptionFilter\":{\"vnfInstanceIds\":[\"vnfId\"]},\"notificationTypes\":[\"VnfLcmOperationOccurrenceNotification\"]},\"callbackUri\":\"https://so-vnfm-adapter.onap:30406/so/vnfm-adapter/v1/lcn/VnfLcmOperationOccurrenceNotification\",\"authentication\":{\"authType\":[\"OAUTH2_CLIENT_CREDENTIALS\", \"BASIC\"],\"paramsOauth2ClientCredentials\":{\"clientId\":\"vnfm\",\"clientPassword\":\"password1$\",\"tokenEndpoint\":\"https://so-vnfm-adapter.onap:30406/oauth/token\"},\"paramsBasic\":{\"userName\":\"vnfm\",\"password\":\"password1$\"}}}";
final InlineResponse2001 subscriptionResponse = new InlineResponse2001();
final InlineResponse201 createResponse = createCreateResponse();
package org.onap.svnfm.simulator.services;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonParser;
+import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
+import javax.net.ssl.HttpsURLConnection;
import javax.ws.rs.core.MediaType;
import org.apache.commons.codec.binary.Base64;
import org.modelmapper.ModelMapper;
import org.onap.so.adapters.vnfmadapter.extclients.vnfm.model.InlineResponse200;
import org.onap.so.adapters.vnfmadapter.extclients.vnfm.model.InlineResponse201InstantiatedVnfInfoVnfcResourceInfo;
import org.onap.so.adapters.vnfmadapter.extclients.vnfm.model.SubscriptionsAuthenticationParamsBasic;
+import org.onap.so.adapters.vnfmadapter.extclients.vnfm.model.SubscriptionsAuthenticationParamsOauth2ClientCredentials;
import org.onap.svnfm.simulator.config.ApplicationConfig;
import org.onap.svnfm.simulator.model.VnfOperation;
import org.onap.svnfm.simulator.model.Vnfds;
final String auth =
subscriptionAuthentication.getUserName() + ":" + subscriptionAuthentication.getPassword();
final byte[] encodedAuth = Base64.encodeBase64(auth.getBytes(StandardCharsets.ISO_8859_1));
- final String authHeader = "Basic " + new String(encodedAuth);
+ String authHeader = "Basic " + new String(encodedAuth);
+
notificationClient.lcnVnfLcmOperationOccurrenceNotificationPostWithHttpInfo(notification,
MediaType.APPLICATION_JSON, authHeader);
} catch (final ApiException exception) {
private InlineResponse201 sendGrantRequest(final GrantRequest grantRequest) {
LOGGER.info("Sending grant request: {}", grantRequest);
try {
+
+ final SubscriptionsAuthenticationParamsOauth2ClientCredentials subscriptionAuthentication =
+ subscriptionService.getSubscriptions().iterator().next().getAuthentication()
+ .getParamsOauth2ClientCredentials();
+ final String authHeader =
+ "Bearer " + getToken(notificationClient.getApiClient(), subscriptionAuthentication);
+
final ApiResponse<InlineResponse201> response = grantClient.grantsPostWithHttpInfo(grantRequest,
- MediaType.APPLICATION_JSON, MediaType.APPLICATION_JSON, "Basic dm5mbTpwYXNzd29yZDEk");
+ MediaType.APPLICATION_JSON, MediaType.APPLICATION_JSON, authHeader);
LOGGER.info("Grant Response: {}", response);
return response.getData();
} catch (final org.onap.so.adapters.vnfmadapter.extclients.vnfm.grant.ApiException exception) {
return applicationConfig.getBaseUrl() + "/vnflcm/v1";
}
+ private String getToken(final ApiClient apiClient,
+ final SubscriptionsAuthenticationParamsOauth2ClientCredentials oauthClientCredentials) {
+ final String basePath = apiClient.getBasePath().substring(0, apiClient.getBasePath().indexOf("/so/"));
+ final String tokenUrl = basePath + "/oauth/token?grant_type=client_credentials";
+
+ try {
+ URL url = new URL(tokenUrl);
+ HttpsURLConnection connection = (HttpsURLConnection) url.openConnection();
+ connection.setRequestMethod("POST");
+ final String authorizationHeader = getAuthorizationHeader(oauthClientCredentials);
+ connection.addRequestProperty("Authorization", authorizationHeader);
+
+ connection.connect();
+
+ return getResponse(connection).get("access_token").getAsString();
+
+ } catch (IOException exception) {
+ LOGGER.error("Error getting token", exception);
+ return null;
+ }
+ }
+
+ private String getAuthorizationHeader(
+ final SubscriptionsAuthenticationParamsOauth2ClientCredentials oauthClientCredentials) {
+ final String auth = oauthClientCredentials.getClientId() + ":" + oauthClientCredentials.getClientPassword();
+ final byte[] encodedAuth = Base64.encodeBase64(auth.getBytes(StandardCharsets.UTF_8));
+ return "Basic " + new String(encodedAuth);
+ }
+
+ private JsonObject getResponse(HttpsURLConnection connection) throws IOException {
+ BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
+ String line, data = "";
+ while ((line = in.readLine()) != null) {
+ data += line;
+ }
+ in.close();
+ connection.getInputStream().close();
+
+ JsonObject jsonObject = new JsonParser().parse(data).getAsJsonObject();
+ return jsonObject;
+ }
+
}