package org.apereo.cas.support.oauth.authenticator; import org.apereo.cas.authentication.Authentication; import org.apereo.cas.authentication.AuthenticationResult; import org.apereo.cas.authentication.AuthenticationSystemSupport; import org.apereo.cas.authentication.UsernamePasswordCredential; import org.apereo.cas.authentication.principal.Principal; import org.apereo.cas.authentication.principal.Service; import org.apereo.cas.authentication.principal.ServiceFactory; import org.apereo.cas.services.RegisteredService; import org.apereo.cas.services.RegisteredServiceAccessStrategyUtils; import org.apereo.cas.services.ServicesManager; import org.apereo.cas.support.oauth.OAuth20Constants; import org.apereo.cas.support.oauth.profile.OAuthUserProfile; import org.apereo.cas.support.oauth.util.OAuth20Utils; import org.pac4j.core.context.WebContext; import org.pac4j.core.credentials.UsernamePasswordCredentials; import org.pac4j.core.credentials.authenticator.Authenticator; import org.pac4j.core.exception.CredentialsException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.Map; /** * Authenticator for user credentials authentication. * * @author Jerome Leleu * @since 5.0.0 */ public class OAuthUserAuthenticator implements Authenticator<UsernamePasswordCredentials> { private static final Logger LOGGER = LoggerFactory.getLogger(OAuthUserAuthenticator.class); private final AuthenticationSystemSupport authenticationSystemSupport; private final ServicesManager servicesManager; private final ServiceFactory webApplicationServiceFactory; public OAuthUserAuthenticator(final AuthenticationSystemSupport authenticationSystemSupport, final ServicesManager servicesManager, final ServiceFactory webApplicationServiceFactory) { this.authenticationSystemSupport = authenticationSystemSupport; this.servicesManager = servicesManager; this.webApplicationServiceFactory = webApplicationServiceFactory; } @Override public void validate(final UsernamePasswordCredentials credentials, final WebContext context) throws CredentialsException { final UsernamePasswordCredential casCredential = new UsernamePasswordCredential(credentials.getUsername(), credentials.getPassword()); try { final String clientId = context.getRequestParameter(OAuth20Constants.CLIENT_ID); final Service service = this.webApplicationServiceFactory.createService(clientId); final RegisteredService registeredService = OAuth20Utils.getRegisteredOAuthService(this.servicesManager, clientId); RegisteredServiceAccessStrategyUtils.ensureServiceAccessIsAllowed(registeredService); final AuthenticationResult authenticationResult = this.authenticationSystemSupport .handleAndFinalizeSingleAuthenticationTransaction(null, casCredential); final Authentication authentication = authenticationResult.getAuthentication(); final Principal principal = authentication.getPrincipal(); final OAuthUserProfile profile = new OAuthUserProfile(); final String id = registeredService.getUsernameAttributeProvider().resolveUsername(principal, service, registeredService); LOGGER.debug("Created profile id [{}]", id); profile.setId(id); final Map<String, Object> attributes = registeredService.getAttributeReleasePolicy().getAttributes(principal, service, registeredService); profile.addAttributes(attributes); LOGGER.debug("Authenticated user profile [{}]", profile); credentials.setUserProfile(profile); } catch (final Exception e) { throw new CredentialsException("Cannot login user using CAS internal authentication", e); } } }