Search in sources :

Example 1 with OIDCC4UIProvider

use of org.apache.syncope.core.persistence.api.entity.OIDCC4UIProvider in project syncope by apache.

the class OIDCC4UILogic method login.

@PreAuthorize("hasRole('" + IdRepoEntitlement.ANONYMOUS + "')")
public OIDCLoginResponse login(final String redirectURI, final String authorizationCode, final String opName) {
    // 0. look for OP
    OIDCC4UIProvider op = opDAO.findByName(opName);
    if (op == null) {
        throw new NotFoundException("OIDC Provider '" + opName + '\'');
    }
    // 1. look for configured client
    OidcClient oidcClient = getOidcClient(opName, redirectURI);
    oidcClient.setCallbackUrl(redirectURI);
    // 2. get OpenID Connect tokens
    String idTokenHint;
    JWTClaimsSet idToken;
    try {
        OidcCredentials credentials = new OidcCredentials();
        credentials.setCode(new AuthorizationCode(authorizationCode));
        OIDC4UIContext ctx = new OIDC4UIContext();
        oidcClient.getAuthenticator().validate(credentials, ctx, NoOpSessionStore.INSTANCE);
        idToken = credentials.getIdToken().getJWTClaimsSet();
        idTokenHint = credentials.getIdToken().serialize();
    } catch (Exception e) {
        LOG.error("While validating Token Response", e);
        SyncopeClientException sce = SyncopeClientException.build(ClientExceptionType.Unknown);
        sce.getElements().add(e.getMessage());
        throw sce;
    }
    // 3. prepare the result
    OIDCLoginResponse loginResponse = new OIDCLoginResponse();
    loginResponse.setLogoutSupported(StringUtils.isNotBlank(op.getEndSessionEndpoint()));
    // 3a. find matching user (if any) and return the received attributes
    String keyValue = idToken.getSubject();
    for (OIDCC4UIProviderItem item : op.getItems()) {
        Attr attrTO = new Attr();
        attrTO.setSchema(item.getExtAttrName());
        String value = idToken.getClaim(item.getExtAttrName()) == null ? null : idToken.getClaim(item.getExtAttrName()).toString();
        if (value != null) {
            attrTO.getValues().add(value);
            loginResponse.getAttrs().add(attrTO);
            if (item.isConnObjectKey()) {
                keyValue = value;
            }
        }
    }
    List<String> matchingUsers = keyValue == null ? List.of() : userManager.findMatchingUser(keyValue, op.getConnObjectKeyItem().get());
    LOG.debug("Found {} matching users for {}", matchingUsers.size(), keyValue);
    // 3b. not found: create or selfreg if configured
    String username;
    if (matchingUsers.isEmpty()) {
        if (op.isCreateUnmatching()) {
            LOG.debug("No user matching {}, about to create", keyValue);
            String defaultUsername = keyValue;
            username = AuthContextUtils.callAsAdmin(AuthContextUtils.getDomain(), () -> userManager.create(op, loginResponse, defaultUsername));
        } else if (op.isSelfRegUnmatching()) {
            UserTO userTO = new UserTO();
            userManager.fill(op, loginResponse, userTO);
            loginResponse.getAttrs().clear();
            loginResponse.getAttrs().addAll(userTO.getPlainAttrs());
            if (StringUtils.isNotBlank(userTO.getUsername())) {
                loginResponse.setUsername(userTO.getUsername());
            } else {
                loginResponse.setUsername(keyValue);
            }
            loginResponse.setSelfReg(true);
            return loginResponse;
        } else {
            throw new NotFoundException(Optional.ofNullable(keyValue).map(value -> "User matching the provided value " + value).orElse("User marching the provided claims"));
        }
    } else if (matchingUsers.size() > 1) {
        throw new IllegalArgumentException("Several users match the provided value " + keyValue);
    } else {
        if (op.isUpdateMatching()) {
            LOG.debug("About to update {} for {}", matchingUsers.get(0), keyValue);
            username = AuthContextUtils.callAsAdmin(AuthContextUtils.getDomain(), () -> userManager.update(matchingUsers.get(0), op, loginResponse));
        } else {
            username = matchingUsers.get(0);
        }
    }
    loginResponse.setUsername(username);
    // 4. generate JWT for further access
    Map<String, Object> claims = new HashMap<>();
    claims.put(JWT_CLAIM_OP_NAME, opName);
    claims.put(JWT_CLAIM_ID_TOKEN, idTokenHint);
    byte[] authorities = null;
    try {
        authorities = ENCRYPTOR.encode(POJOHelper.serialize(authDataAccessor.getAuthorities(loginResponse.getUsername(), null)), CipherAlgorithm.AES).getBytes();
    } catch (Exception e) {
        LOG.error("Could not fetch authorities", e);
    }
    Pair<String, OffsetDateTime> accessTokenInfo = accessTokenDataBinder.create(loginResponse.getUsername(), claims, authorities, true);
    loginResponse.setAccessToken(accessTokenInfo.getLeft());
    loginResponse.setAccessTokenExpiryTime(accessTokenInfo.getRight());
    return loginResponse;
}
Also used : OIDCC4UIProvider(org.apache.syncope.core.persistence.api.entity.OIDCC4UIProvider) Attr(org.apache.syncope.common.lib.Attr) NoOpSessionStore(org.apache.syncope.core.logic.oidc.NoOpSessionStore) POJOHelper(org.apache.syncope.core.provisioning.api.serialization.POJOHelper) OidcCredentials(org.pac4j.oidc.credentials.OidcCredentials) SyncopeClientException(org.apache.syncope.common.lib.SyncopeClientException) OIDC4UIContext(org.apache.syncope.core.logic.oidc.OIDC4UIContext) PreAuthorize(org.springframework.security.access.prepost.PreAuthorize) JWTClaimsSet(com.nimbusds.jwt.JWTClaimsSet) HashMap(java.util.HashMap) StringUtils(org.apache.commons.lang3.StringUtils) OIDCLoginResponse(org.apache.syncope.common.lib.oidc.OIDCLoginResponse) EntityTO(org.apache.syncope.common.lib.to.EntityTO) Pair(org.apache.commons.lang3.tuple.Pair) OidcClient(org.pac4j.oidc.client.OidcClient) OIDCC4UIProviderItem(org.apache.syncope.core.persistence.api.entity.OIDCC4UIProviderItem) Map(java.util.Map) ClientExceptionType(org.apache.syncope.common.lib.types.ClientExceptionType) AuthContextUtils(org.apache.syncope.core.spring.security.AuthContextUtils) ParseException(java.text.ParseException) OIDCClientCache(org.apache.syncope.core.logic.oidc.OIDCClientCache) Method(java.lang.reflect.Method) CipherAlgorithm(org.apache.syncope.common.lib.types.CipherAlgorithm) OidcProfile(org.pac4j.oidc.profile.OidcProfile) Encryptor(org.apache.syncope.core.spring.security.Encryptor) AccessTokenDataBinder(org.apache.syncope.core.provisioning.api.data.AccessTokenDataBinder) WithLocationAction(org.pac4j.core.exception.http.WithLocationAction) AuthDataAccessor(org.apache.syncope.core.spring.security.AuthDataAccessor) SignedJWT(com.nimbusds.jwt.SignedJWT) IdRepoEntitlement(org.apache.syncope.common.lib.types.IdRepoEntitlement) NotFoundException(org.apache.syncope.core.persistence.api.dao.NotFoundException) OIDCUserManager(org.apache.syncope.core.logic.oidc.OIDCUserManager) List(java.util.List) OffsetDateTime(java.time.OffsetDateTime) AuthorizationCode(com.nimbusds.oauth2.sdk.AuthorizationCode) OIDCC4UIProviderDAO(org.apache.syncope.core.persistence.api.dao.OIDCC4UIProviderDAO) Optional(java.util.Optional) OIDCRequest(org.apache.syncope.common.lib.oidc.OIDCRequest) UserTO(org.apache.syncope.common.lib.to.UserTO) AuthorizationCode(com.nimbusds.oauth2.sdk.AuthorizationCode) OIDC4UIContext(org.apache.syncope.core.logic.oidc.OIDC4UIContext) OIDCC4UIProviderItem(org.apache.syncope.core.persistence.api.entity.OIDCC4UIProviderItem) HashMap(java.util.HashMap) SyncopeClientException(org.apache.syncope.common.lib.SyncopeClientException) NotFoundException(org.apache.syncope.core.persistence.api.dao.NotFoundException) SyncopeClientException(org.apache.syncope.common.lib.SyncopeClientException) ParseException(java.text.ParseException) NotFoundException(org.apache.syncope.core.persistence.api.dao.NotFoundException) Attr(org.apache.syncope.common.lib.Attr) OIDCC4UIProvider(org.apache.syncope.core.persistence.api.entity.OIDCC4UIProvider) OIDCLoginResponse(org.apache.syncope.common.lib.oidc.OIDCLoginResponse) OidcCredentials(org.pac4j.oidc.credentials.OidcCredentials) OidcClient(org.pac4j.oidc.client.OidcClient) OffsetDateTime(java.time.OffsetDateTime) JWTClaimsSet(com.nimbusds.jwt.JWTClaimsSet) UserTO(org.apache.syncope.common.lib.to.UserTO) PreAuthorize(org.springframework.security.access.prepost.PreAuthorize)

Example 2 with OIDCC4UIProvider

use of org.apache.syncope.core.persistence.api.entity.OIDCC4UIProvider in project syncope by apache.

the class OIDCC4UIProviderLogic method update.

@PreAuthorize("hasRole('" + OIDC4UIEntitlement.OP_UPDATE + "')")
public void update(final OIDCC4UIProviderTO opTO) {
    OIDCC4UIProvider op = opDAO.find(opTO.getKey());
    if (op == null) {
        throw new NotFoundException("OIDC Provider '" + opTO.getKey() + '\'');
    }
    if (!op.getIssuer().equals(opTO.getIssuer())) {
        LOG.error("Issuers do not match: expected {}, found {}", op.getIssuer(), opTO.getIssuer());
        SyncopeClientException sce = SyncopeClientException.build(ClientExceptionType.InvalidEntity);
        sce.getElements().add("Issuers do not match");
        throw sce;
    }
    String opName = op.getName();
    opDAO.save(binder.update(op, opTO));
    oidcClientClientCache.removeAll(opName);
}
Also used : SyncopeClientException(org.apache.syncope.common.lib.SyncopeClientException) NotFoundException(org.apache.syncope.core.persistence.api.dao.NotFoundException) OIDCC4UIProvider(org.apache.syncope.core.persistence.api.entity.OIDCC4UIProvider) PreAuthorize(org.springframework.security.access.prepost.PreAuthorize)

Example 3 with OIDCC4UIProvider

use of org.apache.syncope.core.persistence.api.entity.OIDCC4UIProvider in project syncope by apache.

the class OIDCC4UIProviderLogic method create.

@PreAuthorize("hasRole('" + OIDC4UIEntitlement.OP_CREATE + "')")
public String create(final OIDCC4UIProviderTO opTO) {
    if (opTO.getConnObjectKeyItem() == null) {
        ItemTO connObjectKeyItem = new ItemTO();
        connObjectKeyItem.setIntAttrName("username");
        connObjectKeyItem.setExtAttrName("email");
        opTO.setConnObjectKeyItem(connObjectKeyItem);
    }
    OIDCC4UIProvider provider = opDAO.save(binder.create(opTO));
    return provider.getKey();
}
Also used : ItemTO(org.apache.syncope.common.lib.to.ItemTO) OIDCC4UIProvider(org.apache.syncope.core.persistence.api.entity.OIDCC4UIProvider) PreAuthorize(org.springframework.security.access.prepost.PreAuthorize)

Example 4 with OIDCC4UIProvider

use of org.apache.syncope.core.persistence.api.entity.OIDCC4UIProvider in project syncope by apache.

the class OIDCC4UIProviderLogic method delete.

@PreAuthorize("hasRole('" + OIDC4UIEntitlement.OP_DELETE + "')")
public void delete(final String key) {
    OIDCC4UIProvider op = opDAO.find(key);
    if (op == null) {
        throw new NotFoundException("OIDC Provider '" + key + '\'');
    }
    String opName = op.getName();
    opDAO.delete(key);
    oidcClientClientCache.removeAll(opName);
}
Also used : NotFoundException(org.apache.syncope.core.persistence.api.dao.NotFoundException) OIDCC4UIProvider(org.apache.syncope.core.persistence.api.entity.OIDCC4UIProvider) PreAuthorize(org.springframework.security.access.prepost.PreAuthorize)

Example 5 with OIDCC4UIProvider

use of org.apache.syncope.core.persistence.api.entity.OIDCC4UIProvider in project syncope by apache.

the class JPAOIDCC4UIProviderDAO method findByName.

@Transactional(readOnly = true)
@Override
public OIDCC4UIProvider findByName(final String name) {
    TypedQuery<OIDCC4UIProvider> query = entityManager().createQuery("SELECT e FROM " + JPAOIDCC4UIProvider.class.getSimpleName() + " e WHERE e.name = :name", OIDCC4UIProvider.class);
    query.setParameter("name", name);
    OIDCC4UIProvider result = null;
    try {
        result = query.getSingleResult();
    } catch (NoResultException e) {
        LOG.debug("No OIDC Provider found with name {}", name, e);
    }
    return result;
}
Also used : JPAOIDCC4UIProvider(org.apache.syncope.core.persistence.jpa.entity.JPAOIDCC4UIProvider) NoResultException(javax.persistence.NoResultException) OIDCC4UIProvider(org.apache.syncope.core.persistence.api.entity.OIDCC4UIProvider) JPAOIDCC4UIProvider(org.apache.syncope.core.persistence.jpa.entity.JPAOIDCC4UIProvider) Transactional(org.springframework.transaction.annotation.Transactional)

Aggregations

OIDCC4UIProvider (org.apache.syncope.core.persistence.api.entity.OIDCC4UIProvider)5 PreAuthorize (org.springframework.security.access.prepost.PreAuthorize)4 NotFoundException (org.apache.syncope.core.persistence.api.dao.NotFoundException)3 SyncopeClientException (org.apache.syncope.common.lib.SyncopeClientException)2 JWTClaimsSet (com.nimbusds.jwt.JWTClaimsSet)1 SignedJWT (com.nimbusds.jwt.SignedJWT)1 AuthorizationCode (com.nimbusds.oauth2.sdk.AuthorizationCode)1 Method (java.lang.reflect.Method)1 ParseException (java.text.ParseException)1 OffsetDateTime (java.time.OffsetDateTime)1 HashMap (java.util.HashMap)1 List (java.util.List)1 Map (java.util.Map)1 Optional (java.util.Optional)1 NoResultException (javax.persistence.NoResultException)1 StringUtils (org.apache.commons.lang3.StringUtils)1 Pair (org.apache.commons.lang3.tuple.Pair)1 Attr (org.apache.syncope.common.lib.Attr)1 OIDCLoginResponse (org.apache.syncope.common.lib.oidc.OIDCLoginResponse)1 OIDCRequest (org.apache.syncope.common.lib.oidc.OIDCRequest)1