-
Notifications
You must be signed in to change notification settings - Fork 44
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Try to implement JIT account provisioning
for OPs
- Loading branch information
Showing
6 changed files
with
187 additions
and
11 deletions.
There are no files selected for viewing
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
80 changes: 80 additions & 0 deletions
80
.../java/it/infn/mw/iam/authn/oidc/service/JustInTimeProvisioningOIDCUserDetailsService.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,80 @@ | ||
package it.infn.mw.iam.authn.oidc.service; | ||
|
||
import java.util.Optional; | ||
import java.util.Set; | ||
import java.util.UUID; | ||
|
||
import org.mitre.openid.connect.model.OIDCAuthenticationToken; | ||
import org.springframework.security.core.userdetails.UsernameNotFoundException; | ||
|
||
import it.infn.mw.iam.authn.InactiveAccountAuthenticationHander; | ||
import it.infn.mw.iam.core.user.IamAccountService; | ||
import it.infn.mw.iam.persistence.model.IamAccount; | ||
import it.infn.mw.iam.persistence.model.IamOidcId; | ||
import it.infn.mw.iam.persistence.repository.IamAccountRepository; | ||
|
||
public class JustInTimeProvisioningOIDCUserDetailsService extends DefaultOidcUserDetailsService { | ||
|
||
private final IamAccountService accountService; | ||
private final Optional<Set<String>> trustedIdpEntityIds; | ||
|
||
public JustInTimeProvisioningOIDCUserDetailsService(IamAccountRepository repo, | ||
InactiveAccountAuthenticationHander handler, IamAccountService accountService, | ||
Optional<Set<String>> trustedIdpEntityIds) { | ||
super(repo, handler); | ||
this.accountService = accountService; | ||
this.trustedIdpEntityIds = trustedIdpEntityIds; | ||
} | ||
|
||
private void checkTrustedIdp(String issuer) { | ||
trustedIdpEntityIds.ifPresent(trustedIds -> { | ||
if (!trustedIds.contains(issuer)) { | ||
throw new UsernameNotFoundException( | ||
String.format("OIDC issuer '%s' is not trusted for JIT provisioning.", issuer)); | ||
} | ||
}); | ||
} | ||
|
||
private void checkRequiredClaims(OIDCAuthenticationToken token) { | ||
if (token.getUserInfo().getGivenName() == null || token.getUserInfo().getFamilyName() == null | ||
|| token.getUserInfo().getEmail() == null) { | ||
throw new UsernameNotFoundException("OIDC token is missing required claims."); | ||
} | ||
} | ||
|
||
private IamAccount provisionAccount(OIDCAuthenticationToken token) { | ||
checkTrustedIdp(token.getIssuer().toString()); | ||
checkRequiredClaims(token); | ||
|
||
IamAccount newAccount = IamAccount.newAccount(); | ||
newAccount.setUsername(UUID.randomUUID().toString()); | ||
newAccount.setProvisioned(true); | ||
|
||
IamOidcId oidcId = new IamOidcId(); | ||
oidcId.setIssuer(token.getIssuer()); | ||
oidcId.setSubject(token.getSub()); | ||
oidcId.setAccount(newAccount); | ||
|
||
newAccount.getOidcIds().add(oidcId); | ||
|
||
newAccount.setActive(true); | ||
|
||
newAccount.getUserInfo().setGivenName(token.getUserInfo().getGivenName()); | ||
newAccount.getUserInfo().setFamilyName(token.getUserInfo().getFamilyName()); | ||
newAccount.getUserInfo().setEmail(token.getUserInfo().getEmail()); | ||
|
||
accountService.createAccount(newAccount); | ||
return newAccount; | ||
} | ||
|
||
@Override | ||
public Object loadUserByOIDC(OIDCAuthenticationToken token) { | ||
Optional<IamAccount> account = repo.findByOidcId(token.getIssuer().toString(), token.getSub()); | ||
|
||
if (account.isPresent()) { | ||
return buildUserFromIamAccount(account.get()); | ||
} else { | ||
return buildUserFromIamAccount(provisionAccount(token)); | ||
} | ||
} | ||
} |
78 changes: 78 additions & 0 deletions
78
...ice/src/main/java/it/infn/mw/iam/config/oidc/IamOidcJITAccountProvisioningProperties.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,78 @@ | ||
package it.infn.mw.iam.config.oidc; | ||
|
||
import java.util.Optional; | ||
import java.util.Set; | ||
|
||
import org.springframework.boot.context.properties.ConfigurationProperties; | ||
import org.springframework.validation.annotation.Validated; | ||
|
||
import com.google.common.base.Splitter; | ||
import com.google.common.collect.Sets; | ||
|
||
@Validated | ||
@ConfigurationProperties(prefix = "oidc.jit-account-provisioning") | ||
public class IamOidcJITAccountProvisioningProperties { | ||
|
||
private boolean enabled; | ||
private String trustedIdps = "all"; | ||
private boolean cleanupTaskEnabled; | ||
private long cleanupTaskPeriodSec = 86400; | ||
private int inactiveAccountLifetimeDays = 15; | ||
|
||
// Getters e Setters | ||
public boolean isEnabled() { | ||
return enabled; | ||
} | ||
|
||
public void setEnabled(boolean enabled) { | ||
this.enabled = enabled; | ||
} | ||
|
||
public String getTrustedIdps() { | ||
return trustedIdps; | ||
} | ||
|
||
public void setTrustedIdps(String trustedIdps) { | ||
this.trustedIdps = trustedIdps; | ||
} | ||
|
||
public Optional<Set<String>> getTrustedIdpsAsOptionalSet() { | ||
if ("all".equals(trustedIdps)) { | ||
return Optional.empty(); | ||
} | ||
|
||
Set<String> trustedIdpIds = | ||
Sets.newHashSet(Splitter.on(",").trimResults().omitEmptyStrings().split(trustedIdps)); | ||
|
||
if (trustedIdpIds.isEmpty()) { | ||
return Optional.empty(); | ||
} | ||
|
||
return Optional.of(trustedIdpIds); | ||
} | ||
|
||
public boolean isCleanupTaskEnabled() { | ||
return cleanupTaskEnabled; | ||
} | ||
|
||
public void setCleanupTaskEnabled(boolean cleanupTaskEnabled) { | ||
this.cleanupTaskEnabled = cleanupTaskEnabled; | ||
} | ||
|
||
public long getCleanupTaskPeriodSec() { | ||
return cleanupTaskPeriodSec; | ||
} | ||
|
||
public void setCleanupTaskPeriodSec(long cleanupTaskPeriodSec) { | ||
this.cleanupTaskPeriodSec = cleanupTaskPeriodSec; | ||
} | ||
|
||
public int getInactiveAccountLifetimeDays() { | ||
return inactiveAccountLifetimeDays; | ||
} | ||
|
||
public void setInactiveAccountLifetimeDays(int inactiveAccountLifetimeDays) { | ||
this.inactiveAccountLifetimeDays = inactiveAccountLifetimeDays; | ||
} | ||
} | ||
|
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