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

io.dialob.boot.security.ApiServiceSecurityConfigurer Maven / Gradle / Ivy

There is a newer version: 2.2.3
Show newest version
/*
 * Copyright © 2015 - 2021 ReSys ([email protected])
 *
 * 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.dialob.boot.security;

import edu.umd.cs.findbugs.annotations.NonNull;
import io.dialob.security.key.ServletRequestApiKeyExtractor;
import io.dialob.security.spring.AuthenticationStrategy;
import io.dialob.security.spring.apikey.ApiKeyAuthoritiesProvider;
import io.dialob.security.spring.apikey.ApiKeyRequestMatcher;
import io.dialob.security.spring.apikey.ApiKeyValidator;
import io.dialob.security.spring.apikey.ClientApiKeyService;
import io.dialob.security.spring.filter.ApiKeyAuthenticationFilter;
import io.dialob.security.spring.tenant.TenantAccessEvaluator;
import io.dialob.settings.DialobSettings;
import org.apache.commons.lang3.StringUtils;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.core.env.Environment;
import org.springframework.core.env.Profiles;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
import org.springframework.security.config.annotation.web.configurers.HeadersConfigurer;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.AnonymousAuthenticationFilter;
import org.springframework.security.web.util.matcher.AndRequestMatcher;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import org.springframework.security.web.util.matcher.AnyRequestMatcher;
import org.springframework.security.web.util.matcher.RequestMatcher;

import java.util.ArrayList;
import java.util.List;


@Configuration
public class ApiServiceSecurityConfigurer extends AbstractApiSecurityConfigurer {

  public static final RequestMatcher SESSION_NOT_EXISTS_MATCHER = request -> request.getSession(false) == null;

  private final ClientApiKeyService apiKeyService;

  private final ApiKeyAuthoritiesProvider apiKeyAuthoritiesProvider;

  private final ServletRequestApiKeyExtractor keyRequestExtractor;

  private final ApiKeyValidator apiKeyValidator;

  private final AuthenticationManager authenticationManager;

  private final boolean allRequests;

  private RequestMatcher requestMatcher;

  private RequestMatcher apiKeyRequestMatcher;

  public ApiServiceSecurityConfigurer(@NonNull ClientApiKeyService apiKeyService,
                                      @NonNull ApiKeyAuthoritiesProvider apiKeyAuthoritiesProvider,
                                      @NonNull ApiKeyValidator apiKeyValidator,
                                      @NonNull DialobSettings settings,
                                      @NonNull ServletRequestApiKeyExtractor keyRequestExtractor,
                                      @NonNull TenantAccessEvaluator tenantPermissionEvaluator,
                                      @NonNull AuthenticationStrategy authenticationStrategy,
                                      @NonNull AuthenticationManager authenticationManager,
                                      @NonNull Environment env) {
    super(settings.getApi().getContextPath(), tenantPermissionEvaluator, authenticationStrategy);
    this.apiKeyService = apiKeyService;
    this.apiKeyAuthoritiesProvider = apiKeyAuthoritiesProvider;
    this.keyRequestExtractor = keyRequestExtractor;
    this.apiKeyValidator = apiKeyValidator;
    this.authenticationManager = authenticationManager;
    this.allRequests = env.acceptsProfiles(Profiles.of("!ui"));
  }

  protected RequestMatcher apiKeyRequestMatcher() {
    if (apiKeyRequestMatcher == null) {
      if (allRequests) {
        apiKeyRequestMatcher = AnyRequestMatcher.INSTANCE;
      } else {
        apiKeyRequestMatcher = new ApiKeyRequestMatcher(this.keyRequestExtractor);
      }
    }
    return apiKeyRequestMatcher;
  }

  protected RequestMatcher requestMatcher() {
    if (requestMatcher == null) {
      List requestMatchers = new ArrayList<>();
      if (StringUtils.isNotBlank(getContextPath())) {
        requestMatchers.add(new AntPathRequestMatcher(getContextPath() + "/**"));
      }
      if (!allRequests) {
        requestMatchers.add(SESSION_NOT_EXISTS_MATCHER);
        requestMatchers.add(apiKeyRequestMatcher());
      }
      if (requestMatchers.isEmpty()) {
        requestMatcher = AnyRequestMatcher.INSTANCE;
      } else {
        requestMatcher = new AndRequestMatcher(requestMatchers);
      }
    }
    return requestMatcher;
  }

  @Override
  protected HttpSecurity configureAuthentication(HttpSecurity http) throws Exception {
    // Disable authentication
    return http
      .sessionManagement((configurer) -> configurer.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
      .logout(AbstractHttpConfigurer::disable);
  }

  @Override
  protected HttpSecurity configureCsrf(HttpSecurity http) throws Exception {
    return http.csrf(AbstractHttpConfigurer::disable);
  }

  @Override
  protected HttpSecurity configureFrameOptions(HttpSecurity http) throws Exception {
    return http.headers(customizer -> customizer.frameOptions(HeadersConfigurer.FrameOptionsConfig::disable));
  }

  @Override
  protected HttpSecurity configureMDCPrincipalFilter(HttpSecurity http) throws Exception {
    return super.configureMDCPrincipalFilter(http)
      .addFilterBefore(new ApiKeyAuthenticationFilter(
          authenticationManager,
          keyRequestExtractor,
          apiKeyRequestMatcher()),
        AnonymousAuthenticationFilter.class);
  }

  @Bean
  @Order(Ordered.HIGHEST_PRECEDENCE)
  SecurityFilterChain apiFilterChain(HttpSecurity http) throws Exception {
    return super.filterChain(http);
  }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy