-
Notifications
You must be signed in to change notification settings - Fork 188
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'support-4.7' of https://github.com/Evolveum/midpoint in…
…to support-4.7
- Loading branch information
Showing
19 changed files
with
1,159 additions
and
33 deletions.
There are no files selected for viewing
203 changes: 203 additions & 0 deletions
203
infra/common/src/main/java/com/evolveum/midpoint/common/RoleMiningExportUtils.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,203 @@ | ||
/* | ||
* Copyright (C) 2010-2023 Evolveum and contributors | ||
* | ||
* This work is dual-licensed under the Apache License 2.0 | ||
* and European Union Public License. See LICENSE file for details. | ||
*/ | ||
|
||
package com.evolveum.midpoint.common; | ||
|
||
import java.io.Serializable; | ||
import java.nio.ByteBuffer; | ||
import java.nio.charset.StandardCharsets; | ||
import java.security.SecureRandom; | ||
import java.util.Base64; | ||
import java.util.List; | ||
import java.util.UUID; | ||
import javax.crypto.Cipher; | ||
import javax.crypto.spec.SecretKeySpec; | ||
|
||
import org.apache.commons.lang3.RandomStringUtils; | ||
import org.jetbrains.annotations.NotNull; | ||
|
||
import com.evolveum.midpoint.xml.ns._public.common.common_3.AssignmentType; | ||
import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectReferenceType; | ||
import com.evolveum.prism.xml.ns._public.types_3.PolyStringType; | ||
|
||
import org.jetbrains.annotations.Nullable; | ||
|
||
public class RoleMiningExportUtils implements Serializable { | ||
|
||
public static final String APPLICATION_ROLE_IDENTIFIER = "Application role"; | ||
public static final String BUSINESS_ROLE_IDENTIFIER = "Business role"; | ||
private static final String EXPORT_SUFFIX = "_AE"; | ||
|
||
public enum NameMode { | ||
ENCRYPTED("ENCRYPTED"), | ||
SEQUENTIAL("SEQUENTIAL"), | ||
ORIGINAL("ORIGINAL"); | ||
|
||
private final String displayString; | ||
|
||
NameMode(String displayString) { | ||
this.displayString = displayString; | ||
} | ||
|
||
public String getDisplayString() { | ||
return displayString; | ||
} | ||
} | ||
|
||
public enum SecurityMode { | ||
STANDARD("STANDARD"), | ||
ADVANCED("ADVANCED"); | ||
private final String displayString; | ||
|
||
SecurityMode(String displayString) { | ||
this.displayString = displayString; | ||
} | ||
|
||
public String getDisplayString() { | ||
return displayString; | ||
} | ||
} | ||
|
||
private static PolyStringType encryptName(String name, int iterator, String prefix, @NotNull NameMode nameMode, String key) { | ||
if (nameMode.equals(NameMode.ENCRYPTED)) { | ||
return PolyStringType.fromOrig(encrypt(name, key) + EXPORT_SUFFIX); | ||
} else if (nameMode.equals(NameMode.SEQUENTIAL)) { | ||
return PolyStringType.fromOrig(prefix + iterator + EXPORT_SUFFIX); | ||
} else if (nameMode.equals(NameMode.ORIGINAL)) { | ||
return PolyStringType.fromOrig(name + EXPORT_SUFFIX); | ||
} | ||
return PolyStringType.fromOrig(prefix + iterator + EXPORT_SUFFIX); | ||
} | ||
|
||
public static PolyStringType encryptUserName(String name, int iterator, NameMode nameMode, String key) { | ||
return encryptName(name, iterator, "User", nameMode, key); | ||
} | ||
|
||
public static PolyStringType encryptOrgName(String name, int iterator, NameMode nameMode, String key) { | ||
return encryptName(name, iterator, "Organization", nameMode, key); | ||
} | ||
|
||
public static PolyStringType encryptRoleName(String name, int iterator, NameMode nameMode, String key) { | ||
return encryptName(name, iterator, "Role", nameMode, key); | ||
} | ||
|
||
public static AssignmentType encryptObjectReference(@NotNull AssignmentType assignmentObject, | ||
SecurityMode securityMode, String key) { | ||
ObjectReferenceType encryptedTargetRef = assignmentObject.getTargetRef(); | ||
encryptedTargetRef.setOid(encryptedUUID(encryptedTargetRef.getOid(), securityMode, key)); | ||
return new AssignmentType().targetRef(encryptedTargetRef); | ||
} | ||
|
||
public static String encryptedUUID(String oid, SecurityMode securityMode, String key) { | ||
UUID uuid = UUID.fromString(oid); | ||
byte[] bytes = uuidToBytes(uuid, securityMode); | ||
return UUID.nameUUIDFromBytes(encryptOid(bytes, key).getBytes()).toString(); | ||
} | ||
|
||
private static byte @NotNull [] uuidToBytes(UUID uuid, @NotNull SecurityMode securityMode) { | ||
ByteBuffer buffer = ByteBuffer.allocate(32); | ||
if (securityMode.equals(SecurityMode.STANDARD)) { | ||
buffer = ByteBuffer.allocate(16); | ||
} | ||
buffer.putLong(uuid.getMostSignificantBits()); | ||
buffer.putLong(uuid.getLeastSignificantBits()); | ||
return buffer.array(); | ||
} | ||
|
||
private static String encryptOid(byte[] value, String key) { | ||
|
||
if (value == null) { | ||
return null; | ||
} | ||
else if (key == null) { | ||
return new String(value, StandardCharsets.UTF_8); | ||
} | ||
|
||
Cipher cipher; | ||
byte[] ciphertext; | ||
try { | ||
byte[] keyBytes = key.getBytes(); | ||
cipher = Cipher.getInstance("AES"); | ||
SecretKeySpec keySpec = new SecretKeySpec(keyBytes, "AES"); | ||
cipher.init(Cipher.ENCRYPT_MODE, keySpec); | ||
ciphertext = cipher.doFinal(value); | ||
return Base64.getEncoder().encodeToString(ciphertext); | ||
} catch (Exception e) { | ||
throw new UnsupportedOperationException(getErrorEncryptMessage(e)); | ||
} | ||
} | ||
|
||
private static String encrypt(String value, String key) { | ||
|
||
if (value == null) { | ||
return null; | ||
} else if (key == null) { | ||
return value; | ||
} | ||
|
||
Cipher cipher; | ||
byte[] ciphertext; | ||
try { | ||
byte[] keyBytes = key.getBytes(); | ||
cipher = Cipher.getInstance("AES"); | ||
SecretKeySpec keySpec = new SecretKeySpec(keyBytes, "AES"); | ||
cipher.init(Cipher.ENCRYPT_MODE, keySpec); | ||
ciphertext = cipher.doFinal(value.getBytes(StandardCharsets.UTF_8)); | ||
return Base64.getEncoder().encodeToString(ciphertext); | ||
} catch (Exception e) { | ||
throw new UnsupportedOperationException(getErrorEncryptMessage(e)); | ||
} | ||
} | ||
|
||
public static @NotNull String updateEncryptKey(@NotNull SecurityMode securityMode) { | ||
int keyLength = 32; | ||
if (securityMode.equals(SecurityMode.STANDARD)) { | ||
keyLength = 16; | ||
} | ||
|
||
return RandomStringUtils.random(keyLength, 0, 0, true, true, null, | ||
new SecureRandom()); | ||
} | ||
|
||
public static @Nullable String determineRoleCategory(String name, List<String> applicationRolePrefix, | ||
List<String> businessRolePrefix, List<String> applicationRoleSuffix, List<String> businessRoleSuffix) { | ||
|
||
if (applicationRolePrefix != null && !applicationRolePrefix.isEmpty()) { | ||
if (applicationRolePrefix.stream().anyMatch(rolePrefix -> name.toLowerCase().startsWith(rolePrefix.toLowerCase()))) { | ||
return APPLICATION_ROLE_IDENTIFIER; | ||
} | ||
} | ||
|
||
if (applicationRoleSuffix != null && !applicationRoleSuffix.isEmpty()) { | ||
if (applicationRoleSuffix.stream().anyMatch(roleSuffix -> name.toLowerCase().endsWith(roleSuffix.toLowerCase()))) { | ||
return APPLICATION_ROLE_IDENTIFIER; | ||
} | ||
} | ||
|
||
if (businessRolePrefix != null && !businessRolePrefix.isEmpty()) { | ||
if (businessRolePrefix.stream().anyMatch(rolePrefix -> name.toLowerCase().startsWith(rolePrefix.toLowerCase()))) { | ||
return BUSINESS_ROLE_IDENTIFIER; | ||
} | ||
} | ||
|
||
if (businessRoleSuffix != null && !businessRoleSuffix.isEmpty()) { | ||
if (businessRoleSuffix.stream().anyMatch(roleSuffix -> name.toLowerCase().endsWith(roleSuffix.toLowerCase()))) { | ||
return BUSINESS_ROLE_IDENTIFIER; | ||
} | ||
} | ||
return null; | ||
} | ||
|
||
private static @NotNull String getErrorEncryptMessage(@NotNull Exception e) { | ||
return "Error: Invalid key - Possible causes:\n" | ||
+ "- The key is not the right size or format for this operation.\n" | ||
+ "- The key is not appropriate for the selected algorithm or mode of operation.\n" | ||
+ "- The key has been damaged or corrupted.\n" | ||
+ "Error message: " + e.getMessage(); | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
44 changes: 44 additions & 0 deletions
44
.../com/evolveum/midpoint/authentication/impl/filter/RefuseUnauthenticatedRequestFilter.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
/* | ||
* Copyright (C) 2010-2023 Evolveum and contributors | ||
* | ||
* This work is dual-licensed under the Apache License 2.0 | ||
* and European Union Public License. See LICENSE file for details. | ||
*/ | ||
|
||
package com.evolveum.midpoint.authentication.impl.filter; | ||
|
||
import com.evolveum.midpoint.authentication.api.config.MidpointAuthentication; | ||
import com.evolveum.midpoint.authentication.impl.util.AuthSequenceUtil; | ||
|
||
import com.evolveum.midpoint.util.logging.Trace; | ||
import com.evolveum.midpoint.util.logging.TraceManager; | ||
|
||
import org.springframework.security.authentication.AuthenticationServiceException; | ||
import org.springframework.security.core.Authentication; | ||
import org.springframework.security.core.context.SecurityContextHolder; | ||
import org.springframework.web.filter.OncePerRequestFilter; | ||
|
||
import javax.servlet.FilterChain; | ||
import javax.servlet.ServletException; | ||
import javax.servlet.http.HttpServletRequest; | ||
import javax.servlet.http.HttpServletResponse; | ||
import java.io.IOException; | ||
|
||
public class RefuseUnauthenticatedRequestFilter extends OncePerRequestFilter { | ||
|
||
private static final Trace LOGGER = TraceManager.getTrace(RefuseUnauthenticatedRequestFilter.class); | ||
|
||
@Override | ||
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { | ||
Authentication mpAuthentication = SecurityContextHolder.getContext().getAuthentication(); | ||
if (AuthSequenceUtil.isPermitAll(request) | ||
|| AuthSequenceUtil.isLoginPage(request) | ||
|| (mpAuthentication instanceof MidpointAuthentication && mpAuthentication.isAuthenticated())) { | ||
filterChain.doFilter(request, response); | ||
return; | ||
} | ||
|
||
LOGGER.debug("Unauthenticated request"); | ||
throw new AuthenticationServiceException("Unauthenticated request"); | ||
} | ||
} |
21 changes: 21 additions & 0 deletions
21
...n/java/com/evolveum/midpoint/authentication/impl/ldap/AuditedAuthenticationException.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
/* | ||
* Copyright (C) 2010-2023 Evolveum and contributors | ||
* | ||
* This work is dual-licensed under the Apache License 2.0 | ||
* and European Union Public License. See LICENSE file for details. | ||
*/ | ||
|
||
package com.evolveum.midpoint.authentication.impl.ldap; | ||
|
||
import org.springframework.security.core.AuthenticationException; | ||
|
||
public class AuditedAuthenticationException extends AuthenticationException { | ||
public AuditedAuthenticationException(AuthenticationException cause) { | ||
super(cause.getMessage(), cause); | ||
} | ||
|
||
@Override | ||
public synchronized AuthenticationException getCause() { | ||
return (AuthenticationException) super.getCause(); | ||
} | ||
} |
Oops, something went wrong.