use of org.graylog2.shared.security.AuthenticationServiceUnavailableException in project graylog2-server by Graylog2.
the class UsernamePasswordRealm method doGetAuthenticationInfo.
private AuthenticationInfo doGetAuthenticationInfo(UsernamePasswordToken token) throws AuthenticationException {
final String username = token.getUsername();
final String plainPassword = String.valueOf(token.getPassword());
if (isBlank(username) || isBlank(plainPassword)) {
LOG.error("Username or password were empty. Not attempting authentication service authentication");
return null;
}
if (rootUsername.equals(username)) {
LOG.debug("Authentication services should not handle the local admin user <{}> - skipping", username);
return null;
}
LOG.debug("Attempting authentication for username <{}>", username);
try {
// We encrypt the password before passing it on to reduce the chance of exposing it somewhere by accident.
final EncryptedValue encryptedPassword = encryptedValueService.encrypt(plainPassword);
final AuthServiceResult result = authenticator.authenticate(AuthServiceCredentials.create(username, encryptedPassword));
if (result.isSuccess()) {
LOG.debug("Successfully authenticated username <{}> for user profile <{}> with backend <{}/{}/{}>", result.username(), result.userProfileId(), result.backendTitle(), result.backendType(), result.backendId());
return toAuthenticationInfo(result);
} else {
LOG.debug("Failed to authenticate username <{}> with backend <{}/{}/{}>", result.username(), result.backendTitle(), result.backendType(), result.backendId());
return null;
}
} catch (AuthServiceException e) {
throw new AuthenticationServiceUnavailableException("Authentication service error", e);
} catch (AuthenticationServiceUnavailableException e) {
throw e;
} catch (Exception e) {
LOG.error("Unhandled authentication error", e);
return null;
}
}
use of org.graylog2.shared.security.AuthenticationServiceUnavailableException in project graylog2-server by Graylog2.
the class ADAuthServiceBackend method authenticateAndProvision.
@Override
public Optional<AuthenticationDetails> authenticateAndProvision(AuthServiceCredentials authCredentials, ProvisionerService provisionerService) {
try (final LDAPConnection connection = ldapConnector.connect(config.getLDAPConnectorConfig())) {
if (connection == null) {
return Optional.empty();
}
final Optional<LDAPUser> optionalUser = findUser(connection, authCredentials);
if (!optionalUser.isPresent()) {
LOG.debug("User <{}> not found in Active Directory", authCredentials.username());
return Optional.empty();
}
final LDAPUser userEntry = optionalUser.get();
if (!userEntry.accountIsEnabled()) {
LOG.warn("Account disabled within Active Directory for user <{}> (DN: {})", authCredentials.username(), userEntry.dn());
return Optional.empty();
}
if (!authCredentials.isAuthenticated()) {
if (!isAuthenticated(connection, userEntry, authCredentials)) {
LOG.debug("Invalid credentials for user <{}> (DN: {})", authCredentials.username(), userEntry.dn());
return Optional.empty();
}
}
final UserDetails userDetails = provisionerService.provision(provisionerService.newDetails(this).authServiceType(backendType()).authServiceId(backendId()).base64AuthServiceUid(userEntry.base64UniqueId()).username(userEntry.username()).accountIsEnabled(userEntry.accountIsEnabled()).fullName(userEntry.fullName()).email(userEntry.email()).defaultRoles(backend.defaultRoles()).build());
return Optional.of(AuthenticationDetails.builder().userDetails(userDetails).build());
} catch (GeneralSecurityException e) {
LOG.error("Error setting up TLS connection", e);
throw new AuthenticationServiceUnavailableException("Error setting up TLS connection", e);
} catch (LDAPException e) {
LOG.error("ActiveDirectory error", e);
throw new AuthenticationServiceUnavailableException("ActiveDirectory error", e);
}
}
use of org.graylog2.shared.security.AuthenticationServiceUnavailableException in project graylog2-server by Graylog2.
the class AuthServiceAuthenticator method authenticate.
/**
* Tries to authenticate the username with the given password and returns the authenticated username if successful.
*
* @param authCredentials the authentication credentials
* @return the authenticated username
*/
public AuthServiceResult authenticate(AuthServiceCredentials authCredentials) {
final Optional<AuthServiceBackend> activeBackend = authServiceConfig.getActiveBackend();
if (activeBackend.isPresent()) {
AuthenticationServiceUnavailableException caughtException = null;
try {
final AuthServiceResult result = authenticate(authCredentials, activeBackend.get());
if (result.isSuccess()) {
return result;
}
} catch (AuthenticationServiceUnavailableException e) {
caughtException = e;
}
// TODO: Do we want the fallback to the default backend here? Maybe it should be configurable?
if (LOG.isDebugEnabled()) {
final AuthServiceBackend defaultBackend = authServiceConfig.getDefaultBackend();
LOG.debug("Couldn't authenticate <{}> against active authentication service <{}/{}/{}>. Trying default backend <{}/{}/{}>.", authCredentials.username(), activeBackend.get().backendId(), activeBackend.get().backendType(), activeBackend.get().backendTitle(), defaultBackend.backendId(), defaultBackend.backendType(), defaultBackend.backendTitle());
}
final AuthServiceResult result = authenticate(authCredentials, authServiceConfig.getDefaultBackend());
if (result.isSuccess()) {
return result;
}
if (caughtException != null) {
throw caughtException;
}
return result;
} else {
return authenticate(authCredentials, authServiceConfig.getDefaultBackend());
}
}
use of org.graylog2.shared.security.AuthenticationServiceUnavailableException in project graylog2-server by Graylog2.
the class SessionsResource method newSession.
@POST
@ApiOperation(value = "Create a new session", notes = "This request creates a new session for a user or " + "reactivates an existing session: the equivalent of logging in.")
@NoAuditEvent("dispatches audit events in the method body")
public JsonNode newSession(@Context ContainerRequestContext requestContext, @ApiParam(name = "Login request", value = "Credentials. The default " + "implementation requires presence of two properties: 'username' and " + "'password'. However a plugin may customize which kind of credentials " + "are accepted and therefore expect different properties.", required = true) @NotNull JsonNode createRequest) {
final SecurityContext securityContext = requestContext.getSecurityContext();
if (!(securityContext instanceof ShiroSecurityContext)) {
throw new InternalServerErrorException("Unsupported SecurityContext class, this is a bug!");
}
final ShiroSecurityContext shiroSecurityContext = (ShiroSecurityContext) securityContext;
final ActorAwareAuthenticationToken authToken;
try {
authToken = tokenFactory.forRequestBody(createRequest);
} catch (IllegalArgumentException e) {
throw new BadRequestException(e.getMessage());
}
// we treat the BASIC auth username as the sessionid
final String sessionId = shiroSecurityContext.getUsername();
final String host = RestTools.getRemoteAddrFromRequest(grizzlyRequest, trustedSubnets);
try {
Optional<Session> session = sessionCreator.create(sessionId, host, authToken);
if (session.isPresent()) {
return sessionResponseFactory.forSession(session.get());
} else {
throw new NotAuthorizedException("Invalid credentials.", "Basic realm=\"Graylog Server session\"");
}
} catch (AuthenticationServiceUnavailableException e) {
throw new ServiceUnavailableException("Authentication service unavailable");
}
}
use of org.graylog2.shared.security.AuthenticationServiceUnavailableException in project graylog2-server by Graylog2.
the class SessionCreator method create.
/**
* Attempts to log the user in with the given authentication token and returns a new or renewed session upon
* success.
* <p>
* Side effect: the user will be registered with the current security context.
*
* @param currentSessionId A session id, if one exists currently.
* @param host Host the request to create a session originates from.
* @param authToken Authentication token to log the user in.
* @return A session for the authenticated user wrapped in an {@link Optional}, or an empty {@link Optional} if
* authentication failed.
* @throws AuthenticationServiceUnavailableException If authenticating the user fails not due to an issue with the
* credentials but because of an external resource being
* unavailable
*/
public Optional<Session> create(@Nullable String currentSessionId, String host, ActorAwareAuthenticationToken authToken) throws AuthenticationServiceUnavailableException {
final String previousSessionId = StringUtils.defaultIfBlank(currentSessionId, null);
final Subject subject = new Subject.Builder().sessionId(previousSessionId).host(host).buildSubject();
ThreadContext.bind(subject);
try {
final Session session = subject.getSession();
subject.login(authToken);
String userId = subject.getPrincipal().toString();
final User user = userService.loadById(userId);
if (user != null) {
long timeoutInMillis = user.getSessionTimeoutMs();
session.setTimeout(timeoutInMillis);
session.setAttribute("username", user.getName());
getSessionAttributes(subject).forEach(session::setAttribute);
} else {
// set a sane default. really we should be able to load the user from above.
session.setTimeout(UserImpl.DEFAULT_SESSION_TIMEOUT_MS);
}
session.touch();
// save subject in session, otherwise we can't get the username back in subsequent requests.
((DefaultSecurityManager) SecurityUtils.getSecurityManager()).getSubjectDAO().save(subject);
final Map<String, Object> auditEventContext = ImmutableMap.of("session_id", session.getId(), "remote_address", host);
auditEventSender.success(AuditActor.user(user.getName()), SESSION_CREATE, auditEventContext);
return Optional.of(session);
} catch (AuthenticationServiceUnavailableException e) {
log.info("Session creation failed due to authentication service being unavailable. Actor: \"{}\"", authToken.getActor().urn());
final Map<String, Object> auditEventContext = ImmutableMap.of("remote_address", host, "message", "Authentication service unavailable: " + e.getMessage());
auditEventSender.failure(authToken.getActor(), SESSION_CREATE, auditEventContext);
throw e;
} catch (AuthenticationException e) {
log.info("Invalid credentials in session create request. Actor: \"{}\"", authToken.getActor().urn());
final Map<String, Object> auditEventContext = ImmutableMap.of("remote_address", host);
auditEventSender.failure(authToken.getActor(), SESSION_CREATE, auditEventContext);
return Optional.empty();
}
}
Aggregations