![JAR search and dependency download from the Maven repository](/logo.png)
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.AdminInitiateAuthRequest;
import com.amazonaws.services.cognitoidp.model.AdminInitiateAuthResult;
import com.amazonaws.services.cognitoidp.model.AttributeType;
import com.amazonaws.services.cognitoidp.model.AuthFlowType;
import com.amazonaws.services.cognitoidp.model.AuthenticationResultType;
import com.amazonaws.services.cognitoidp.model.GetUserRequest;
import com.amazonaws.services.cognitoidp.model.GetUserResult;
import com.amazonaws.services.cognitoidp.model.GlobalSignOutRequest;
import com.amazonaws.services.cognitoidp.model.NotAuthorizedException;
import com.amazonaws.services.cognitoidp.model.UserNotFoundException;
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 io.polyglotted.spring.web.SimpleResponse;
import lombok.RequiredArgsConstructor;
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.MapBuilder.simpleMap;
import static io.polyglotted.common.util.MapRetriever.listVal;
import static io.polyglotted.common.util.StrUtil.notNullOrEmpty;
import static io.polyglotted.common.util.StrUtil.nullOrEmpty;
import static io.polyglotted.common.util.StrUtil.safePrefix;
import static io.polyglotted.spring.errorhandling.ExceptionFactory.checkBadRequest;
import static io.polyglotted.spring.errorhandling.ExceptionFactory.unauthorisedException;
import static java.util.Locale.ENGLISH;
import static org.apache.commons.codec.binary.Base64.decodeBase64;
import static org.apache.http.HttpHeaders.AUTHORIZATION;
@Slf4j @Component @RequiredArgsConstructor
public class CognitoProcessor {
private final CognitoConfig config;
private final AWSCognitoIdentityProvider cognitoClient;
@Autowired private ObjectMapper objectMapper = null;
public AuthenticationResultType login(String email, String password) {
checkBadRequest(notNullOrEmpty(email) && notNullOrEmpty(password), "Invalid credentials.");
try {
AdminInitiateAuthRequest authRequest = new AdminInitiateAuthRequest()
.withAuthFlow(AuthFlowType.ADMIN_NO_SRP_AUTH).withAuthParameters(simpleMap("USERNAME", email, "PASSWORD", password,
"SECRET_HASH", config.getClientSecret())).withClientId(config.getClientId()).withUserPoolId(config.getUserPoolId());
AdminInitiateAuthResult authResponse = cognitoClient.adminInitiateAuth(authRequest);
if (nullOrEmpty(authResponse.getChallengeName())) { return authResponse.getAuthenticationResult(); }
throw unauthorisedException("Unexpected challenge on signin: " + authResponse.getChallengeName() + ".");
} catch (UserNotFoundException | NotAuthorizedException ex) {
log.debug("not found or invalid creds: {}", email); throw unauthorisedException(safePrefix(ex.getMessage(), " ("));
}
}
public SimpleResponse logout(String accessToken) {
try {
cognitoClient.globalSignOut(new GlobalSignOutRequest().withAccessToken(accessToken));
} catch (Exception ex) { log.warn("failed to logout " + accessToken); }
return new SimpleResponse("logged-out");
}
DefaultAuthToken authenticate(HttpServletRequest request) {
if (config.disabled()) { return null; }
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(), header, 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.toUpperCase(); }
private static List authorities(List roles) {
return transformList(roles, role -> new SimpleGrantedAuthority("ROLE_" + role.toUpperCase()));
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy