Search in sources :

Example 1 with ActorAwareAuthenticationToken

use of org.graylog2.shared.security.ActorAwareAuthenticationToken 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 2 with ActorAwareAuthenticationToken

use of org.graylog2.shared.security.ActorAwareAuthenticationToken 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

Session (org.apache.shiro.session.Session)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 AuthenticationException (org.apache.shiro.authc.AuthenticationException)1 Subject (org.apache.shiro.subject.Subject)1 NoAuditEvent (org.graylog2.audit.jersey.NoAuditEvent)1 User (org.graylog2.plugin.database.users.User)1 ActorAwareAuthenticationToken (org.graylog2.shared.security.ActorAwareAuthenticationToken)1 AuthenticationServiceUnavailableException (org.graylog2.shared.security.AuthenticationServiceUnavailableException)1 ShiroSecurityContext (org.graylog2.shared.security.ShiroSecurityContext)1