Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
141 commits
Select commit Hold shift + click to select a range
8e24f0e
feat(idp): add identity provider configuration entity and repository
mjabascal10 Oct 29, 2025
7bfe403
feat(oauth2): implement corporate authentication with OAuth2 support
mjabascal10 Oct 30, 2025
070a93a
feat(oauth2): implement corporate authentication with OAuth2 support
mjabascal10 Oct 30, 2025
a855ca3
feat(oauth2): implement corporate authentication with OAuth2 support
mjabascal10 Oct 30, 2025
b32bc20
feat(login): add login providers component and service
mjabascal10 Oct 30, 2025
1904954
feat(oauth2): implement corporate authentication with OAuth2 support
mjabascal10 Oct 30, 2025
71f07d6
feat(login): add login providers component and service
mjabascal10 Oct 31, 2025
056bf11
refactor(agent): remove unused TLS certificate validation and related…
yllada Oct 31, 2025
cdacd84
fix[frontend](web_console): sanitized password parameter to admit all…
AlexSanchez-bit Oct 16, 2025
8cc7293
Update frontend/src/app/core/auth/account.service.ts
mjabascal10 Oct 31, 2025
96a58b0
fix[frontend](app_settings): added GMT+12 and daylight saving options…
AlexSanchez-bit Oct 16, 2025
28e7046
feat(agent): validate TLS certificates before enabling TLS for integr…
yllada Oct 31, 2025
4b862d3
feat(idp): add identity provider configuration entity and repository
mjabascal10 Oct 29, 2025
d197bf3
feat(oauth2): implement corporate authentication with OAuth2 support
mjabascal10 Oct 30, 2025
6eee4a0
feat(oauth2): implement corporate authentication with OAuth2 support
mjabascal10 Oct 30, 2025
4a7b3c9
feat(oauth2): implement corporate authentication with OAuth2 support
mjabascal10 Oct 30, 2025
504b2d9
feat(login): add login providers component and service
mjabascal10 Oct 30, 2025
74846a5
feat(oauth2): implement corporate authentication with OAuth2 support
mjabascal10 Oct 30, 2025
3c33657
feat(login): add login providers component and service
mjabascal10 Oct 31, 2025
195800e
Merge remote-tracking branch 'origin/backlog/add-oauth2-oidc-corporat…
mjabascal10 Nov 5, 2025
6e739a5
feat(login): enhance login providers UI and add provider icons
mjabascal10 Nov 5, 2025
c31d6c9
Merge branch 'release/v11' into backlog/add-oauth2-oidc-corporate-aut…
mjabascal10 Nov 13, 2025
2f71955
feat(oauth2): implement corporate authentication with OAuth2 support
mjabascal10 Nov 6, 2025
a2cd1b4
feat(identity-provider): add OAuth2/OpenID Connect provider management
mjabascal10 Nov 13, 2025
f1a56c7
feat(identity-provider): add OAuth2/OpenID Connect provider management
mjabascal10 Nov 13, 2025
a418f77
feat: implement service to automatically assign asset groups to alerts
mjabascal10 Nov 13, 2025
ff92207
feat(identity-provider): add OAuth2/OpenID Connect provider management
mjabascal10 Nov 14, 2025
ba38590
Merge remote-tracking branch 'origin/backlog/add-oauth2-oidc-corporat…
mjabascal10 Nov 14, 2025
be1efde
feat(oauth2): enhance corporate authentication with additional fields…
mjabascal10 Nov 16, 2025
d6cd03e
Merge remote-tracking branch 'origin/backlog/add-oauth2-oidc-corporat…
mjabascal10 Nov 16, 2025
7e9cf7c
feat(oauth2): enhance corporate authentication with additional fields…
mjabascal10 Nov 17, 2025
9f33152
feat(oauth2): enhance corporate authentication with additional fields…
mjabascal10 Nov 17, 2025
3fbd456
feat(identity-provider): add OAuth2/OpenID Connect provider management
mjabascal10 Nov 17, 2025
69e27ec
Merge remote-tracking branch 'origin/backlog/add-oauth2-oidc-corporat…
mjabascal10 Nov 17, 2025
8cf74ea
feat(oauth2): enhance corporate authentication with additional fields…
mjabascal10 Nov 17, 2025
a0b5e36
feat(identity-provider): add OAuth2/OpenID Connect provider management
mjabascal10 Nov 17, 2025
c6dec4d
Merge remote-tracking branch 'origin/backlog/add-oauth2-oidc-corporat…
mjabascal10 Nov 17, 2025
ba899a5
Update frontend/src/app/shared/components/auth/login/login.component.ts
mjabascal10 Nov 18, 2025
d2a325a
Update frontend/src/app/shared/components/auth/login-providers/login-…
mjabascal10 Nov 18, 2025
0ab0720
Update backend/src/main/java/com/park/utmstack/config/SecurityConfigu…
mjabascal10 Nov 18, 2025
ac996e2
Update backend/src/main/java/com/park/utmstack/service/idp_provider/I…
mjabascal10 Nov 18, 2025
4dde3a0
Update frontend/src/app/app-management/identity-provider/shared/compo…
mjabascal10 Nov 18, 2025
36e9bd3
Merge remote-tracking branch 'origin/release/v11' into backlog/add-oa…
mjabascal10 Nov 18, 2025
6a55410
feat(oauth2): enhance corporate authentication with additional fields…
mjabascal10 Nov 18, 2025
acc827d
refactor: simplify request structure and improve provider toggle logic
mjabascal10 Nov 18, 2025
ecdf6e3
Merge remote-tracking branch 'origin/backlog/add-oauth2-oidc-corporat…
mjabascal10 Nov 18, 2025
d7076b4
feat(oauth2): implement enterprise version handling for identity prov…
mjabascal10 Nov 18, 2025
56f422e
fix[bitdefender-plugin]: make StartServer blocking and remove retry loop
Kbayero Nov 21, 2025
22b4625
update macos guide
Kbayero Nov 21, 2025
f99558b
fix: adjust TFA expiration time to use configurable constant
mjabascal10 Nov 21, 2025
484b9c1
feat: conditionally render module card based on module name
mjabascal10 Nov 21, 2025
2b4b256
Merge remote-tracking branch 'origin/release/v11.0.2' into release/v1…
mjabascal10 Nov 21, 2025
038d5a7
feat: add application version info retrieval functionality
mjabascal10 Nov 24, 2025
555a485
feat: add application version info retrieval functionality
mjabascal10 Nov 24, 2025
f1a44e5
Merge remote-tracking branch 'origin/release/v11.0.2' into release/v1…
mjabascal10 Nov 24, 2025
64bb9e6
Merge remote-tracking branch 'origin/release/v11.0.2' into release/v1…
mjabascal10 Nov 24, 2025
41f3323
feat(saml): implement SAML authentication support with identity provi…
mjabascal10 Nov 25, 2025
826bbbe
feat(saml): implement SAML authentication support with identity provi…
mjabascal10 Nov 25, 2025
c8eb9aa
Merge remote-tracking branch 'origin/backlog/add-saml-oidc-corporate-…
mjabascal10 Nov 25, 2025
152d247
feat: add application version info retrieval functionality
mjabascal10 Nov 25, 2025
556fcf2
Merge remote-tracking branch 'origin/release/v11.0.2' into release/v1…
mjabascal10 Nov 25, 2025
1008d39
fix: remove conditional rendering for AS_400 module and filter out in…
mjabascal10 Nov 25, 2025
f98cb0b
Merge remote-tracking branch 'origin/release/v11.0.2' into release/v1…
mjabascal10 Nov 25, 2025
f3f48e0
feat(saml): enhance SAML authentication success handler to include ro…
mjabascal10 Nov 25, 2025
809d701
Merge remote-tracking branch 'origin/backlog/add-saml-oidc-corporate-…
mjabascal10 Nov 25, 2025
42a19ad
feat(o365-plugin): add multi-cloud environment support for Microsoft …
JocLRojas Nov 25, 2025
745b463
feat: add exception handling for MethodArgumentNotValidException and …
mjabascal10 Nov 25, 2025
8437b65
fix(o365-plugin): Remove invalid field check and add multi-cloud support
JocLRojas Nov 25, 2025
9f85c83
Merge remote-tracking branch 'origin/release/v11.0.2' into release/v1…
mjabascal10 Nov 25, 2025
49c7efd
feat(o365-plugin): add Office 365 cloud environment configuration opt…
mjabascal10 Nov 25, 2025
3ab94f5
Update backend/src/main/resources/config/liquibase/changelog/20251125…
mjabascal10 Nov 25, 2025
5a26b52
Update backend/src/main/java/com/park/utmstack/domain/application_mod…
mjabascal10 Nov 25, 2025
c33cd57
Update backend/src/main/java/com/park/utmstack/domain/application_mod…
mjabascal10 Nov 25, 2025
40d39f6
Merge pull request #1432 from utmstack/backlog/office-365-cloud-envir…
mjabascal10 Nov 25, 2025
8ef1d24
fix: update file permissions from 777 to 755 for security improvements
osmontero Nov 26, 2025
320a757
Merge branch 'backlog/update-agent-permissions-to-755' into release/v…
osmontero Nov 26, 2025
8e9d7fa
feat(azure plugin): enhance Azure cloud detection and connection vali…
yllada Nov 26, 2025
782793e
feat(o365_validation-modules-config): add Management API validation a…
JocLRojas Nov 26, 2025
632401f
Merge branch 'release/v11.0.2' of https://github.com/utmstack/UTMStac…
JocLRojas Nov 26, 2025
be82425
feat(header): integrate version info display and update logic
mjabascal10 Nov 26, 2025
26e1ea0
refactor: rename UtmStackConnectionService to ModuleConfigurationVali…
mjabascal10 Nov 26, 2025
f67de3f
feat(exception-handling): add ApiException class and global exception…
mjabascal10 Nov 26, 2025
ace938a
feat(int-generic-group-config): improve searchable option based on co…
mjabascal10 Nov 27, 2025
8582e3e
feat(int-generic-group-config): improve searchable option based on co…
mjabascal10 Nov 27, 2025
8c4317a
Merge remote-tracking branch 'origin/release/v11.0.2' into release/v1…
mjabascal10 Nov 27, 2025
17f2638
fix(modules-config): disable CROWDSTRIKE module not implemented in ba…
JocLRojas Nov 27, 2025
483f9a0
refactor(plugins): standardize logging with catcher
JocLRojas Nov 27, 2025
dcbb783
feat(saml): update identity provider configuration to include metadat…
mjabascal10 Nov 28, 2025
e0c5e70
style(dashboard): adjust padding and layout for improved UI consistency
mjabascal10 Nov 28, 2025
0379495
fix: optimize cloud detection logic in connection string parsing
yllada Nov 28, 2025
e70d0ee
feat(elastic-filter-time): enhance time filter functionality and upda…
mjabascal10 Nov 28, 2025
c971157
Merge remote-tracking branch 'origin/release/v11.0.2' into release/v1…
mjabascal10 Nov 28, 2025
b97f5b3
Merge branch 'release/v11.0.2' into backlog/add-saml-oidc-corporate-a…
mjabascal10 Nov 28, 2025
a7355fc
Merge remote-tracking branch 'origin/release/v11.0.2' into backlog/ad…
mjabascal10 Nov 28, 2025
bbba7fe
feat(azure): extract individual records from Azure Event Hub logs
yllada Nov 28, 2025
cc8eb69
fix(modules-config): remove gin default logger middleware to eliminat…
JocLRojas Nov 28, 2025
16ad2e1
refactor(azure-filter): deleted 'Expand log.records' data to improve …
JocLRojas Nov 28, 2025
5071a01
refactor(gcp-filter): deleted 'Expand jsonPayload.structuredRdata' da…
JocLRojas Nov 28, 2025
92cd347
update the version of the Azure and GCP filters
JocLRojas Nov 28, 2025
8bb9dea
feat(saml): update identity provider configuration to include metadat…
mjabascal10 Nov 28, 2025
caec313
feat(provider): add SAML 2.0 support with metadata URL and service pr…
mjabascal10 Nov 28, 2025
f600fbc
feat(saml): enhance identity provider creation with multipart form da…
mjabascal10 Nov 29, 2025
a71b25f
feat(provider): add SAML 2.0 support with metadata URL and service pr…
mjabascal10 Nov 29, 2025
0a2343d
Merge remote-tracking branch 'origin/backlog/add-saml-oidc-corporate-…
mjabascal10 Nov 29, 2025
da3bc60
fix(totp): prevent potential error by checking subscription before un…
mjabascal10 Nov 29, 2025
15e31cd
style(totp): comment out unused email resend container for cleaner code
mjabascal10 Dec 1, 2025
2f43013
style(utm-code-view): add word-break class to code element for better…
mjabascal10 Dec 1, 2025
fdae307
feat(filters): add Azure and GCP filters with updated field mappings …
mjabascal10 Dec 1, 2025
3a9ade8
Merge remote-tracking branch 'origin/v11' into release/v11.0.2
mjabascal10 Dec 1, 2025
d2e3197
Merge remote-tracking branch 'origin/release/v11.0.2' into release/v1…
mjabascal10 Dec 1, 2025
968c9c5
refactor(ModuleSocAi): remove unused getName method for cleaner code
mjabascal10 Dec 1, 2025
dfc5ac8
fix(deployment-pipeline): update tag pattern for v10 to support seman…
mjabascal10 Dec 1, 2025
bb2411a
chore(changelog): update release notes for UTMStack v11.0.3 with fixe…
mjabascal10 Dec 1, 2025
cbeb14c
chore(changelog): update release notes for UTMStack v11.0.3 with fixe…
mjabascal10 Dec 1, 2025
c22ae16
Merge remote-tracking branch 'origin/release/v11.0.2' into backlog/ad…
mjabascal10 Dec 1, 2025
5eb26af
Merge remote-tracking branch 'origin/v11' into backlog/add-saml-oidc-…
mjabascal10 Dec 1, 2025
2a55dee
feat(authentication): add SAML and OIDC support with validation for p…
mjabascal10 Dec 1, 2025
0beb10e
chore(master.xml): remove outdated environment integration and filter…
mjabascal10 Dec 1, 2025
6ba5e3c
feat(identity-provider): enhance provider management with file upload…
mjabascal10 Dec 1, 2025
6ce7c34
feat(authentication): enhance SAML and OIDC support with file validat…
mjabascal10 Dec 1, 2025
cc14c3b
Merge remote-tracking branch 'origin/backlog/add-saml-oidc-corporate-…
mjabascal10 Dec 1, 2025
e98de63
feat(identity-provider): enhance provider management with file upload…
mjabascal10 Dec 1, 2025
f637626
feat(identity-provider): enhance provider management with file upload…
mjabascal10 Dec 1, 2025
9eff950
Merge remote-tracking branch 'origin/release/v11.0.4' into backlog/ad…
mjabascal10 Dec 2, 2025
4e44375
feat: enhance identity provider management with role requirements and…
mjabascal10 Dec 2, 2025
5d08296
feat: update login components for improved styling and provider text
mjabascal10 Dec 2, 2025
402ee6c
feat: add loading screen with spinner and enhance app initialization
mjabascal10 Dec 2, 2025
a92e9ff
feat(agents): update agent guide with Kali Linux tab and enhance inst…
mjabascal10 Dec 2, 2025
684dcc1
feat: add SAML OIDC corporate authentication configuration fields
mjabascal10 Dec 3, 2025
82882c2
feat: add SAML OIDC corporate authentication support with SP entity I…
mjabascal10 Dec 3, 2025
0471c16
feat(api-keys): implement API key management with creation, retrieval…
mjabascal10 Dec 3, 2025
efc5d5e
Merge remote-tracking branch 'origin/backlog/add-saml-oidc-corporate-…
mjabascal10 Dec 3, 2025
d3f7e8a
feat: integrate app version management and enterprise feature directive
mjabascal10 Dec 4, 2025
7d40163
Merge remote-tracking branch 'origin/backlog/add-saml-oidc-corporate-…
mjabascal10 Dec 4, 2025
09284df
feat: enhance SAML2 login handlers with role validation and logging
mjabascal10 Dec 4, 2025
944a709
Merge remote-tracking branch 'origin/backlog/add-saml-oidc-corporate-…
mjabascal10 Dec 4, 2025
6e90beb
feat: enhance SAML2 login handlers with role validation and logging
mjabascal10 Dec 4, 2025
b59706f
feat: enhance SAML2 login handlers with role validation and logging
mjabascal10 Dec 4, 2025
6efe00f
feat: integrate app version management and enterprise feature directive
mjabascal10 Dec 4, 2025
e3428a5
Merge remote-tracking branch 'origin/backlog/add-saml-oidc-corporate-…
mjabascal10 Dec 4, 2025
cb99274
feat: update API route for version checking to check-for-updates
mjabascal10 Dec 4, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions backend/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,11 @@
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>
<!-- SAML2 Service Provider -->
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-saml2-service-provider</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,21 +1,17 @@
package com.park.utmstack.config;

import com.park.utmstack.loggin.api_key.ApiKeyUsageLoggingService;
import com.park.utmstack.loggin.filter.MdcCleanupFilter;
import com.park.utmstack.repository.UserRepository;
import com.park.utmstack.security.AuthoritiesConstants;
import com.park.utmstack.security.api_key.ApiKeyConfigurer;
import com.park.utmstack.security.api_key.ApiKeyFilter;
import com.park.utmstack.security.internalApiKey.InternalApiKeyConfigurer;
import com.park.utmstack.security.internalApiKey.InternalApiKeyProvider;
import com.park.utmstack.security.jwt.JWTConfigurer;
import com.park.utmstack.security.jwt.JWTFilter;
import com.park.utmstack.security.jwt.TokenProvider;
import com.park.utmstack.service.api_key.ApiKeyService;
import com.park.utmstack.security.saml.Saml2LoginFailureHandler;
import com.park.utmstack.security.saml.Saml2LoginSuccessHandler;
import lombok.RequiredArgsConstructor;
import org.apache.commons.net.util.SubnetUtils;
import org.springframework.beans.factory.BeanInitializationException;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
Expand All @@ -35,10 +31,10 @@
import org.springframework.web.filter.CorsFilter;
import org.zalando.problem.spring.web.advice.security.SecurityProblemSupport;


import javax.annotation.PostConstruct;
import javax.servlet.http.HttpServletResponse;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;


@Configuration
@RequiredArgsConstructor
Expand All @@ -53,6 +49,8 @@ public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
private final CorsFilter corsFilter;
private final InternalApiKeyProvider internalApiKeyProvider;
private final ApiKeyFilter apiKeyFilter;
private final UserRepository userRepository;


@PostConstruct
public void init() {
Expand Down Expand Up @@ -110,7 +108,9 @@ public void configure(HttpSecurity http) throws Exception {
.antMatchers("/api/releaseInfo").permitAll()
.antMatchers("/api/account/reset-password/init").permitAll()
.antMatchers("/api/account/reset-password/finish").permitAll()
.antMatchers("/api/utm-providers").permitAll()
.antMatchers("/api/images/all").permitAll()
.antMatchers("/api/info/version").permitAll()
.antMatchers("/api/enrollment/**").hasAnyAuthority(AuthoritiesConstants.PRE_VERIFICATION_USER)
.antMatchers("/api/tfa/verify-code").hasAnyAuthority(AuthoritiesConstants.PRE_VERIFICATION_USER, AuthoritiesConstants.USER, AuthoritiesConstants.ADMIN)
.antMatchers("/api/tfa/refresh").hasAnyAuthority(AuthoritiesConstants.PRE_VERIFICATION_USER, AuthoritiesConstants.USER, AuthoritiesConstants.ADMIN)
Expand All @@ -126,6 +126,12 @@ public void configure(HttpSecurity http) throws Exception {
.antMatchers("/management/info").permitAll()
.antMatchers("/management/**").hasAnyAuthority(AuthoritiesConstants.ADMIN, AuthoritiesConstants.USER)
.and()
.saml2Login()
.successHandler(new Saml2LoginSuccessHandler(tokenProvider,
userRepository,
saml2LoginFailureHandler()))
.failureHandler(new Saml2LoginFailureHandler())
.and()
.apply(securityConfigurerAdapterForJwt())
.and()
.apply(securityConfigurerAdapterForInternalApiKey())
Expand All @@ -147,4 +153,10 @@ private ApiKeyConfigurer securityConfigurerAdapterForApiKey() {
return new ApiKeyConfigurer(apiKeyFilter);
}


@Bean
public Saml2LoginFailureHandler saml2LoginFailureHandler() {
return new Saml2LoginFailureHandler();
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package com.park.utmstack.config.saml;

import com.park.utmstack.repository.idp_provider.IdentityProviderConfigRepository;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class OAuth2ClientConfig {

@Bean
public SamlRelyingPartyRegistrationRepository clientRegistrationRepository(IdentityProviderConfigRepository repo) {
return new SamlRelyingPartyRegistrationRepository(repo);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package com.park.utmstack.config.saml;

import com.park.utmstack.repository.idp_provider.IdentityProviderConfigRepository;
import com.park.utmstack.util.events.ProviderChangedEvent;
import lombok.RequiredArgsConstructor;
import org.springframework.context.event.EventListener;
import org.springframework.security.saml2.provider.service.registration.RelyingPartyRegistrationRepository;
import org.springframework.stereotype.Component;

@Component
@RequiredArgsConstructor
public class ProviderChangeListener {

private final RelyingPartyRegistrationRepository repository;
private final IdentityProviderConfigRepository identityProviderConfigRepository;

@EventListener
public void handleProviderChanged(ProviderChangedEvent event) {
if (repository instanceof SamlRelyingPartyRegistrationRepository customRepo) {
customRepo.reloadProviders(identityProviderConfigRepository);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
package com.park.utmstack.config.saml;

import com.park.utmstack.config.Constants;
import com.park.utmstack.domain.idp_provider.IdentityProviderConfig;
import com.park.utmstack.repository.idp_provider.IdentityProviderConfigRepository;
import com.park.utmstack.util.CipherUtil;
import com.park.utmstack.util.saml.PemUtils;
import org.springframework.security.saml2.core.Saml2X509Credential;
import org.springframework.security.saml2.provider.service.registration.RelyingPartyRegistration;
import org.springframework.security.saml2.provider.service.registration.RelyingPartyRegistrationRepository;
import org.springframework.security.saml2.provider.service.registration.RelyingPartyRegistrations;
import org.springframework.web.servlet.support.ServletUriComponentsBuilder;

import java.security.PrivateKey;
import java.security.cert.X509Certificate;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

public class SamlRelyingPartyRegistrationRepository implements RelyingPartyRegistrationRepository {

private final Map<String, RelyingPartyRegistration> registrations = new ConcurrentHashMap<>();

public SamlRelyingPartyRegistrationRepository(IdentityProviderConfigRepository jpaProviderRepository) {
loadProviders(jpaProviderRepository);
}

@Override
public RelyingPartyRegistration findByRegistrationId(String registrationId) {
return registrations.get(registrationId);
}

public void reloadProviders(IdentityProviderConfigRepository jpaProviderRepository) {
registrations.clear();
loadProviders(jpaProviderRepository);
}

private void loadProviders(IdentityProviderConfigRepository jpaProviderRepository) {
jpaProviderRepository.findAllByActiveTrue().forEach(entity -> {
RelyingPartyRegistration registration = buildRelyingPartyRegistration(entity);
registrations.put(entity.getProviderType().name().toLowerCase(), registration);
});
}

private RelyingPartyRegistration buildRelyingPartyRegistration(IdentityProviderConfig entity) {

PrivateKey spKey = PemUtils.parsePrivateKey(CipherUtil.decrypt(
entity.getSpPrivateKeyPem(),
System.getenv(Constants.ENV_ENCRYPTION_KEY)
));
X509Certificate spCert = PemUtils.parseCertificate(entity.getSpCertificatePem());

return RelyingPartyRegistrations
.fromMetadataLocation(entity.getMetadataUrl())
.registrationId(entity.getName())
.entityId(entity.getSpEntityId())
.assertionConsumerServiceLocation(entity.getSpAcsUrl())
.signingX509Credentials(c -> c.add(Saml2X509Credential.signing(spKey, spCert)))
.build();
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
package com.park.utmstack.domain.idp_provider;

import com.park.utmstack.domain.idp_provider.enums.ProviderType;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import org.hibernate.annotations.Type;

import javax.persistence.*;
import java.time.LocalDateTime;

@Entity
@Table(name = "utm_identity_provider_config")
@Data
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode(onlyExplicitlyIncluded = true)
public class IdentityProviderConfig {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@EqualsAndHashCode.Include
private Long id;

@Column(nullable = false)
private String name;

@Enumerated(EnumType.STRING)
@Column(nullable = false)
private ProviderType providerType;

/**
* Metadata URL of the IdP (Keycloak, Okta, Azure, etc.)
* Example: https://localhost:8443/realms/UTMSTACK/protocol/saml/descriptor
*/
@Column(name = "metadata_url", nullable = false, length = 512)
private String metadataUrl;

/**
* Service Provider private key in PEM format
* Used to sign AuthnRequests and other outgoing SAML messages
*/
@Type(type = "text")
@Column(name = "sp_private_key_pem", nullable = false, columnDefinition = "TEXT")
private String spPrivateKeyPem;

/**
* Service Provider public certificate in PEM format
* Shared with IdP so it can validate signed requests from the SP
*/
@Type(type = "text")
@Column(name = "sp_certificate_pem", nullable = false, columnDefinition = "TEXT")
private String spCertificatePem;

@Column(name = "sp_entity_id", nullable = false, length = 512)
private String spEntityId;

@Column(name = "sp_acs_url", nullable = false, length = 512)
private String spAcsUrl;

/**
* Flag to enable or disable this IdP configuration
*/
@Column(nullable = false)
private Boolean active;

/**
* Timestamp when the record was created
*/
@Column(nullable = false)
private LocalDateTime createdAt;

/**
* Timestamp when the record was last updated
*/
@Column(nullable = false)
private LocalDateTime updatedAt;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package com.park.utmstack.domain.idp_provider.enums;

public enum ProviderType {
GOOGLE,
KEYCLOAK,
OKTA,
MICROSOFT;

public static ProviderType from(String value) {
return ProviderType.valueOf(value.toUpperCase());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package com.park.utmstack.repository.idp_provider;

import com.park.utmstack.domain.idp_provider.IdentityProviderConfig;
import com.park.utmstack.domain.idp_provider.enums.ProviderType;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.stereotype.Repository;

import java.util.List;
import java.util.Optional;

@Repository
public interface IdentityProviderConfigRepository extends JpaRepository<IdentityProviderConfig, Long>, JpaSpecificationExecutor<IdentityProviderConfig> {

Optional<IdentityProviderConfig> findByProviderTypeAndActiveTrue(ProviderType providerType);

List<IdentityProviderConfig> findAllByActiveTrue();
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

public class JWTConfigurer extends SecurityConfigurerAdapter<DefaultSecurityFilterChain, HttpSecurity> {

private TokenProvider tokenProvider;
private final TokenProvider tokenProvider;

public JWTConfigurer(TokenProvider tokenProvider) {
this.tokenProvider = tokenProvider;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package com.park.utmstack.security.saml;

import lombok.extern.slf4j.Slf4j;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.web.util.UriComponentsBuilder;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URI;
import java.util.Objects;

/**
* Failure handler for SAML2 login.
* Redirects the user to the frontend with an error parameter.
*/
@Slf4j
public class Saml2LoginFailureHandler implements AuthenticationFailureHandler {

@Override
public void onAuthenticationFailure(HttpServletRequest request,
HttpServletResponse response,
AuthenticationException exception) throws IOException {

String scheme = Objects.requireNonNullElse(request.getHeader("X-Forwarded-Proto"), request.getScheme());
String host = Objects.requireNonNullElse(request.getHeader("Host"), request.getServerName());

String frontBaseUrl = scheme + "://" + host;

URI redirectUri = UriComponentsBuilder.fromHttpUrl(frontBaseUrl)
.queryParam("error", "saml2")
.build().toUri();

response.sendRedirect(redirectUri.toString());
}
}
Loading