Skip to content

Commit

Permalink
OP-21911: Bugfix sapor gate basic authentication
Browse files Browse the repository at this point in the history
  • Loading branch information
sudhakaropsmx committed Mar 29, 2024
1 parent 471b2ae commit e7fd624
Show file tree
Hide file tree
Showing 6 changed files with 110 additions and 55 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,6 @@

import com.netflix.spinnaker.gate.config.AuthConfig;
import com.netflix.spinnaker.gate.security.SpinnakerAuthConfig;
import com.netflix.spinnaker.gate.services.OesAuthorizationService;
import com.netflix.spinnaker.gate.services.PermissionService;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import lombok.extern.slf4j.Slf4j;
Expand All @@ -28,10 +26,14 @@
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.AuthenticationServiceException;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityCustomizer;
import org.springframework.security.crypto.factory.PasswordEncoderFactories;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint;
import org.springframework.session.web.http.DefaultCookieSerializer;
Expand All @@ -43,9 +45,8 @@
@Slf4j
public class BasicAuthConfig {

private final AuthConfig authConfig;

private final BasicAuthProvider authProvider;
@Autowired private final AuthConfig authConfig;
@Autowired private final BasicAuthProvider authProvider;

@Autowired DefaultCookieSerializer defaultCookieSerializer;

Expand All @@ -58,19 +59,16 @@ public class BasicAuthConfig {
@Value("${security.user.password:}")
String password;

@Autowired PermissionService permissionService;

@Autowired
public BasicAuthConfig(
AuthConfig authConfig,
PermissionService permissionService,
OesAuthorizationService oesAuthorizationService) {
public BasicAuthConfig(AuthConfig authConfig, BasicAuthProvider authProvider) {
this.authConfig = authConfig;
this.authProvider = new BasicAuthProvider(permissionService, oesAuthorizationService);
this.authProvider = authProvider;
}

@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
@Bean
public AuthenticationManager authManager(HttpSecurity http) throws Exception {
AuthenticationManagerBuilder authenticationManagerBuilder =
http.getSharedObject(AuthenticationManagerBuilder.class);
if (name == null || name.isEmpty() || password == null || password.isEmpty()) {
throw new AuthenticationServiceException(
"User credentials are not configured properly. Please check username and password are properly configured");
Expand All @@ -86,18 +84,36 @@ public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception

authProvider.setName(this.name);
authProvider.setPassword(this.password);

auth.authenticationProvider(authProvider);
authenticationManagerBuilder.authenticationProvider(authProvider);
authenticationManagerBuilder.eraseCredentials(false);
return authenticationManagerBuilder.build();
}

@Bean
public SecurityFilterChain configure(HttpSecurity http) throws Exception {
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
defaultCookieSerializer.setSameSite(null);
http.csrf().disable();
http.formLogin()
.and()
.httpBasic()
.authenticationEntryPoint(new LoginUrlAuthenticationEntryPoint("/login"));
authConfig.configure(http);
return http.build();
}

@Bean
public WebSecurityCustomizer webSecurityCustomizer() {
return (web) -> {
try {
authConfig.configure(web);
} catch (Exception e) {
throw new RuntimeException(e);
}
};
}

@Bean
public PasswordEncoder passwordEncoder() {
return PasswordEncoderFactories.createDelegatingPasswordEncoder();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,12 @@

import com.netflix.spinnaker.gate.services.OesAuthorizationService;
import com.netflix.spinnaker.gate.services.PermissionService;
import com.netflix.spinnaker.security.User;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.BadCredentialsException;
Expand All @@ -32,8 +31,12 @@
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Component;

@Slf4j
@Component
public class BasicAuthProvider implements AuthenticationProvider {

private final PermissionService permissionService;
Expand All @@ -46,6 +49,7 @@ public class BasicAuthProvider implements AuthenticationProvider {
@Setter private String name;
@Setter private String password;

@Autowired
public BasicAuthProvider(
PermissionService permissionService, OesAuthorizationService oesAuthorizationService) {
this.permissionService = permissionService;
Expand All @@ -61,29 +65,27 @@ public Authentication authenticate(Authentication authentication) throws Authent
if (!this.name.equals(name) || !this.password.equals(password)) {
throw new BadCredentialsException("Invalid username/password combination");
}

log.debug("roles configured for user: {} are roles: {}", name, roles);
User user = new User();
user.setEmail(name);
user.setUsername(name);
user.setRoles(Collections.singletonList("USER"));

List<GrantedAuthority> grantedAuthorities = new ArrayList<>();

if (roles != null && !roles.isEmpty() && permissionService != null) {
user.setRoles(roles);
grantedAuthorities =
roles.stream().map(role -> new SimpleGrantedAuthority(role)).collect(Collectors.toList());
grantedAuthorities.addAll(
roles.stream()
.map(role -> new SimpleGrantedAuthority(role))
.collect(Collectors.toList()));
// Updating roles in fiat service
permissionService.loginWithRoles(name, roles);
log.info("Platform service enabled value :{}", isPlatformEnabled);
// Updating roles in platform service
if (isPlatformEnabled) {
oesAuthorizationService.cacheUserGroups(roles, name);
}
} else {
grantedAuthorities.add(new SimpleGrantedAuthority("USER"));
}

return new UsernamePasswordAuthenticationToken(user, password, grantedAuthorities);
UserDetails principal = new User(name, password, grantedAuthorities);
return new UsernamePasswordAuthenticationToken(principal, password, grantedAuthorities);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,22 @@ import jakarta.servlet.http.HttpServletResponse
@Slf4j
@RestController
class RootController {

@Value('${services.deck.base-url:}')
URL deckBaseUrl
@Value('${services.oesui.externalUrl:}')
String uiBaseUrl
@Value('${services.gate:oes-gate}')
String gateType

@RequestMapping("/")
void root(HttpServletResponse response) {
log.info("uiBaseUrl : {}", uiBaseUrl)
response.sendRedirect(uiBaseUrl + "/application")
if(gateType.equalsIgnoreCase("oes-gate")){
log.info("uiBaseUrl : {}", uiBaseUrl)
response.sendRedirect(uiBaseUrl + "/application")
} else {
log.info("deckBaseUrl : {}", deckBaseUrl)
response.sendRedirect("/applications")
}

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,9 @@

package com.opsmx.spinnaker.gate.cache;

import com.github.benmanes.caffeine.cache.Caffeine;
import java.util.concurrent.TimeUnit;
import lombok.Getter;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
import org.springframework.cache.CacheManager;
import org.springframework.cache.caffeine.CaffeineCacheManager;
import org.springframework.cache.concurrent.ConcurrentMapCacheManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
Expand All @@ -34,26 +30,10 @@ public class OesCacheManager {

@Getter private CacheManager concurrentMapCacheManager;

@Getter private CaffeineCacheManager caffeineCacheManager;

@Value("${cache.expiryTime:600000}")
private String cacheExpiryTimeout;

@Primary
@Bean(name = "concurrentMapCacheManager")
public CacheManager concurrentMapCacheManager() {
concurrentMapCacheManager = new ConcurrentMapCacheManager("datasource");
return concurrentMapCacheManager;
}

@Bean(name = "caffeineCacheManager")
public CacheManager cacheManager() {

CaffeineCacheManager cacheManager = new CaffeineCacheManager("adminAuth");
cacheManager.setCaffeine(
Caffeine.newBuilder()
.expireAfterWrite(Long.parseLong(cacheExpiryTimeout), TimeUnit.MILLISECONDS));
caffeineCacheManager = cacheManager;
return cacheManager;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/*
* Copyright 2024 Netflix, Inc.
*
* 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 com.opsmx.spinnaker.gate.cache;

import com.github.benmanes.caffeine.cache.Caffeine;
import java.util.concurrent.TimeUnit;
import lombok.Getter;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
import org.springframework.cache.CacheManager;
import org.springframework.cache.caffeine.CaffeineCacheManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
@ConditionalOnExpression("${services.platform.enabled:false}")
public class OesPlatformCacheManager {

@Getter private CaffeineCacheManager caffeineCacheManager;

@Value("${cache.expiryTime:600000}")
private String cacheExpiryTimeout;

@Bean(name = "caffeineCacheManager")
public CacheManager cacheManager() {

CaffeineCacheManager cacheManager = new CaffeineCacheManager("adminAuth");
cacheManager.setCaffeine(
Caffeine.newBuilder()
.expireAfterWrite(Long.parseLong(cacheExpiryTimeout), TimeUnit.MILLISECONDS));
caffeineCacheManager = cacheManager;
return cacheManager;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
package com.opsmx.spinnaker.gate.service;

import com.google.gson.Gson;
import com.opsmx.spinnaker.gate.cache.OesCacheManager;
import com.opsmx.spinnaker.gate.cache.OesPlatformCacheManager;
import com.opsmx.spinnaker.gate.cache.platform.AuthorizationCaching;
import java.util.Map;
import java.util.Set;
Expand All @@ -35,7 +35,7 @@ public class AdminAuthService implements PlatformCachingService {

private Gson gson = new Gson();

@Autowired private OesCacheManager oesCacheManager;
@Autowired private OesPlatformCacheManager oesPlatformCacheManager;

@Autowired private AuthorizationCaching authorizationCaching;

Expand All @@ -50,7 +50,7 @@ public void cacheResponse(Object response, String userName) {
@Override
public boolean isCacheNotEmpty(String userName) {

CacheManager cacheManager = oesCacheManager.getCaffeineCacheManager();
CacheManager cacheManager = oesPlatformCacheManager.getCaffeineCacheManager();
CaffeineCache caffeineCache = (CaffeineCache) cacheManager.getCache("adminAuth");
Set<Object> keySet = caffeineCache.getNativeCache().asMap().keySet();
return keySet.stream()
Expand Down

0 comments on commit e7fd624

Please sign in to comment.