All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.polyglotted.spring.cognito.CognitoProcessor Maven / Gradle / Ivy

package io.polyglotted.spring.cognito;

import com.amazonaws.services.cognitoidp.AWSCognitoIdentityProvider;
import com.amazonaws.services.cognitoidp.model.AttributeType;
import com.amazonaws.services.cognitoidp.model.GetUserRequest;
import com.amazonaws.services.cognitoidp.model.GetUserResult;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.polyglotted.common.model.MapResult;
import io.polyglotted.common.model.Subject;
import io.polyglotted.spring.cognito.CognitoAuthFilter.NotCognitoException;
import io.polyglotted.spring.security.DefaultAuthToken;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import java.util.List;

import static io.polyglotted.common.model.MapResult.simpleResult;
import static io.polyglotted.common.model.Subject.subjectBuilder;
import static io.polyglotted.common.util.BaseSerializer.deserialize;
import static io.polyglotted.common.util.CollUtil.transformList;
import static io.polyglotted.common.util.MapRetriever.listVal;
import static java.util.Locale.ENGLISH;
import static org.apache.commons.codec.binary.Base64.decodeBase64;
import static org.apache.http.HttpHeaders.AUTHORIZATION;

@Slf4j @Component
public class CognitoProcessor extends AbstractCognito {
    @Autowired private ObjectMapper objectMapper = null;

    @Autowired public CognitoProcessor(CognitoConfig config, AWSCognitoIdentityProvider cognitoClient) { super(config, cognitoClient); }

    DefaultAuthToken authenticate(HttpServletRequest request) {
        String header = request.getHeader(AUTHORIZATION);
        if (header != null && header.startsWith("Bearer")) {
            String bearerToken = header.substring(7);
            List roles = fetchRoles(bearerToken);
            return new DefaultAuthToken(getUser(bearerToken).roles(roles).build(), bearerToken, authorities(roles));
        }
        log.trace("No Bearer token found in HTTP Authorization header");
        return null;
    }

    private Subject.Builder getUser(String accessToken) {
        GetUserResult user = cognitoClient.getUser(new GetUserRequest().withAccessToken(accessToken));
        MapResult attributes = simpleResult();
        for (AttributeType type : user.getUserAttributes()) { attributes.put(type.getName().toLowerCase(ENGLISH), type.getValue()); }
        return subjectBuilder().username(attributes.removeVal("sub")).email(attributes.optStr("email"))
            .fullName(attributes.optStr("name")).metadata(attributes);
    }

    private List fetchRoles(String token) {
        String[] parts = token.split("\\.");
        if (parts.length != 3) { throw new NotCognitoException("invalid token parts"); }
        return rolesFrom(deserialize(objectMapper, decodeBase64(parts[1])));
    }

    private static List rolesFrom(MapResult map) { return transformList(listVal(map, "cognito:groups"), CognitoProcessor::groupToRole); }

    private static String groupToRole(String group) { return group.startsWith("ABACI_") ? group.substring(6) : group; }

    private static List authorities(List roles) {
        return transformList(roles, role -> new SimpleGrantedAuthority("ROLE_" + role.toUpperCase()));
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy