Search in sources :

Example 1 with AuthenticationServiceUnavailableException

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;
    }
}
Also used : AuthServiceException(org.graylog.security.authservice.AuthServiceException) AuthServiceResult(org.graylog.security.authservice.AuthServiceResult) EncryptedValue(org.graylog2.security.encryption.EncryptedValue) AuthenticationServiceUnavailableException(org.graylog2.shared.security.AuthenticationServiceUnavailableException) AuthenticationServiceUnavailableException(org.graylog2.shared.security.AuthenticationServiceUnavailableException) AuthenticationException(org.apache.shiro.authc.AuthenticationException) AuthServiceException(org.graylog.security.authservice.AuthServiceException) UnsupportedTokenException(org.apache.shiro.authc.pam.UnsupportedTokenException)

Example 2 with AuthenticationServiceUnavailableException

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);
    }
}
Also used : UserDetails(org.graylog.security.authservice.UserDetails) LDAPException(com.unboundid.ldap.sdk.LDAPException) GeneralSecurityException(java.security.GeneralSecurityException) LDAPUser(org.graylog.security.authservice.ldap.LDAPUser) LDAPConnection(com.unboundid.ldap.sdk.LDAPConnection) AuthenticationServiceUnavailableException(org.graylog2.shared.security.AuthenticationServiceUnavailableException)

Example 3 with AuthenticationServiceUnavailableException

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());
    }
}
Also used : AuthenticationServiceUnavailableException(org.graylog2.shared.security.AuthenticationServiceUnavailableException)

Example 4 with AuthenticationServiceUnavailableException

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");
    }
}
Also used : SecurityContext(javax.ws.rs.core.SecurityContext) ShiroSecurityContext(org.graylog2.shared.security.ShiroSecurityContext) ActorAwareAuthenticationToken(org.graylog2.shared.security.ActorAwareAuthenticationToken) InternalServerErrorException(javax.ws.rs.InternalServerErrorException) BadRequestException(javax.ws.rs.BadRequestException) NotAuthorizedException(javax.ws.rs.NotAuthorizedException) ServiceUnavailableException(javax.ws.rs.ServiceUnavailableException) AuthenticationServiceUnavailableException(org.graylog2.shared.security.AuthenticationServiceUnavailableException) AuthenticationServiceUnavailableException(org.graylog2.shared.security.AuthenticationServiceUnavailableException) ShiroSecurityContext(org.graylog2.shared.security.ShiroSecurityContext) Session(org.apache.shiro.session.Session) POST(javax.ws.rs.POST) ApiOperation(io.swagger.annotations.ApiOperation) NoAuditEvent(org.graylog2.audit.jersey.NoAuditEvent)

Example 5 with AuthenticationServiceUnavailableException

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();
    }
}
Also used : User(org.graylog2.plugin.database.users.User) AuthenticationException(org.apache.shiro.authc.AuthenticationException) ImmutableMap(com.google.common.collect.ImmutableMap) Map(java.util.Map) Subject(org.apache.shiro.subject.Subject) Session(org.apache.shiro.session.Session)

Aggregations

AuthenticationServiceUnavailableException (org.graylog2.shared.security.AuthenticationServiceUnavailableException)5 LDAPConnection (com.unboundid.ldap.sdk.LDAPConnection)2 LDAPException (com.unboundid.ldap.sdk.LDAPException)2 GeneralSecurityException (java.security.GeneralSecurityException)2 AuthenticationException (org.apache.shiro.authc.AuthenticationException)2 Session (org.apache.shiro.session.Session)2 UserDetails (org.graylog.security.authservice.UserDetails)2 LDAPUser (org.graylog.security.authservice.ldap.LDAPUser)2 ImmutableMap (com.google.common.collect.ImmutableMap)1 ApiOperation (io.swagger.annotations.ApiOperation)1 Map (java.util.Map)1 BadRequestException (javax.ws.rs.BadRequestException)1 InternalServerErrorException (javax.ws.rs.InternalServerErrorException)1 NotAuthorizedException (javax.ws.rs.NotAuthorizedException)1 POST (javax.ws.rs.POST)1 ServiceUnavailableException (javax.ws.rs.ServiceUnavailableException)1 SecurityContext (javax.ws.rs.core.SecurityContext)1 UnsupportedTokenException (org.apache.shiro.authc.pam.UnsupportedTokenException)1 Subject (org.apache.shiro.subject.Subject)1 AuthServiceException (org.graylog.security.authservice.AuthServiceException)1