blob: abcb4860575eeb4216a1301a2bbddc0fc3cb986b [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.guacamole.auth.duo;
import com.google.inject.Inject;
import java.util.Collections;
import javax.servlet.http.HttpServletRequest;
import org.apache.guacamole.GuacamoleException;
import org.apache.guacamole.auth.duo.api.DuoService;
import org.apache.guacamole.auth.duo.conf.ConfigurationService;
import org.apache.guacamole.auth.duo.form.DuoSignedResponseField;
import org.apache.guacamole.form.Field;
import org.apache.guacamole.language.TranslatableGuacamoleClientException;
import org.apache.guacamole.language.TranslatableGuacamoleInsufficientCredentialsException;
import org.apache.guacamole.net.auth.AuthenticatedUser;
import org.apache.guacamole.net.auth.Credentials;
import org.apache.guacamole.net.auth.credentials.CredentialsInfo;
/**
* Service for verifying the identity of a user against Duo.
*/
public class UserVerificationService {
/**
* Service for retrieving Duo configuration information.
*/
@Inject
private ConfigurationService confService;
/**
* Service for verifying users against Duo.
*/
@Inject
private DuoService duoService;
/**
* Verifies the identity of the given user via the Duo multi-factor
* authentication service. If a signed response from Duo has not already
* been provided, a signed response from Duo is requested in the
* form of additional expected credentials. Any provided signed response
* is cryptographically verified. If no signed response is present, or the
* signed response is invalid, an exception is thrown.
*
* @param authenticatedUser
* The user whose identity should be verified against Duo.
*
* @throws GuacamoleException
* If required Duo-specific configuration options are missing or
* malformed, or if the user's identity cannot be verified.
*/
public void verifyAuthenticatedUser(AuthenticatedUser authenticatedUser)
throws GuacamoleException {
// Pull the original HTTP request used to authenticate
Credentials credentials = authenticatedUser.getCredentials();
HttpServletRequest request = credentials.getRequest();
// Ignore anonymous users
if (authenticatedUser.getIdentifier().equals(AuthenticatedUser.ANONYMOUS_IDENTIFIER))
return;
// Retrieve signed Duo response from request
String signedResponse = request.getParameter(DuoSignedResponseField.PARAMETER_NAME);
// If no signed response, request one
if (signedResponse == null) {
// Create field which requests a signed response from Duo that
// verifies the identity of the given user via the configured
// Duo API endpoint
Field signedResponseField = new DuoSignedResponseField(
confService.getAPIHostname(),
duoService.createSignedRequest(authenticatedUser));
// Create an overall description of the additional credentials
// required to verify identity
CredentialsInfo expectedCredentials = new CredentialsInfo(
Collections.singletonList(signedResponseField));
// Request additional credentials
throw new TranslatableGuacamoleInsufficientCredentialsException(
"Verification using Duo is required before authentication "
+ "can continue.", "LOGIN.INFO_DUO_AUTH_REQUIRED",
expectedCredentials);
}
// If signed response does not verify this user's identity, abort auth
if (!duoService.isValidSignedResponse(authenticatedUser, signedResponse))
throw new TranslatableGuacamoleClientException("Provided Duo "
+ "validation code is incorrect.",
"LOGIN.INFO_DUO_VALIDATION_CODE_INCORRECT");
}
}