Search in sources :

Example 46 with Session

use of org.apache.shiro.session.Session in project graylog2-server by Graylog2.

the class SessionsResource method validateSession.

@GET
@ApiOperation(value = "Validate an existing session", notes = "Checks the session with the given ID: returns http status 204 (No Content) if session is valid.", code = 204)
public SessionValidationResponse validateSession(@Context ContainerRequestContext requestContext) {
    try {
        this.authenticationFilter.filter(requestContext);
    } catch (NotAuthorizedException | LockedAccountException | IOException e) {
        return SessionValidationResponse.invalid();
    }
    final Subject subject = getSubject();
    if (!subject.isAuthenticated()) {
        return SessionValidationResponse.invalid();
    }
    // session information from the response to perform subsequent requests to the backend using this session.
    if (subject.getSession(false) == null && ShiroSecurityContext.isSessionCreationRequested()) {
        final Session session = subject.getSession();
        final String userId = subject.getPrincipal().toString();
        final User user = userService.loadById(userId);
        if (user == null) {
            throw new InternalServerErrorException("Unable to load user with ID <" + userId + ">.");
        }
        session.setAttribute("username", user.getName());
        final HTTPHeaderAuthConfig httpHeaderConfig = loadHTTPHeaderConfig();
        final Optional<String> usernameHeader = ShiroRequestHeadersBinder.getHeaderFromThreadContext(httpHeaderConfig.usernameHeader());
        if (httpHeaderConfig.enabled() && usernameHeader.isPresent()) {
            session.setAttribute(HTTPHeaderAuthenticationRealm.SESSION_AUTH_HEADER, usernameHeader.get());
        }
        LOG.debug("Create session for <{}>", user.getName());
        session.touch();
        // save subject in session, otherwise we can't get the username back in subsequent requests.
        ((DefaultSecurityManager) SecurityUtils.getSecurityManager()).getSubjectDAO().save(subject);
        return SessionValidationResponse.validWithNewSession(String.valueOf(session.getId()), String.valueOf(user.getName()));
    }
    return SessionValidationResponse.valid();
}
Also used : HTTPHeaderAuthConfig(org.graylog2.security.headerauth.HTTPHeaderAuthConfig) User(org.graylog2.plugin.database.users.User) InternalServerErrorException(javax.ws.rs.InternalServerErrorException) NotAuthorizedException(javax.ws.rs.NotAuthorizedException) IOException(java.io.IOException) LockedAccountException(org.apache.shiro.authc.LockedAccountException) Subject(org.apache.shiro.subject.Subject) Session(org.apache.shiro.session.Session) GET(javax.ws.rs.GET) ApiOperation(io.swagger.annotations.ApiOperation)

Example 47 with Session

use of org.apache.shiro.session.Session 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 48 with Session

use of org.apache.shiro.session.Session 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)

Example 49 with Session

use of org.apache.shiro.session.Session in project graylog2-server by Graylog2.

the class SessionCreatorTest method extendSession.

@Test
public void extendSession() {
    setUpUserMock();
    // Create a session and store it.
    SimpleSession oldSession = new SimpleSession();
    ((DefaultSessionManager) securityManager.getSessionManager()).getSessionDAO().create(oldSession);
    String oldSessionId = oldSession.getId().toString();
    assertFalse(SecurityUtils.getSubject().isAuthenticated());
    Optional<Session> session = sessionCreator.create(oldSessionId, "host", validToken);
    assertTrue(session.isPresent());
    assertEquals(SESSION_TIMEOUT, session.get().getTimeout());
    assertEquals(oldSessionId, session.get().getId());
    assertTrue(SecurityUtils.getSubject().isAuthenticated());
    verify(auditEventSender).success(eq(AuditActor.user("username")), anyString(), anyMap());
}
Also used : Mockito.anyString(org.mockito.Mockito.anyString) SimpleSession(org.apache.shiro.session.mgt.SimpleSession) Session(org.apache.shiro.session.Session) SimpleSession(org.apache.shiro.session.mgt.SimpleSession) Test(org.junit.Test)

Example 50 with Session

use of org.apache.shiro.session.Session in project ddf by codice.

the class OAuthPlugin method process.

/**
 * Verifies that a source configured to use OAuth has a valid access token to process and that the
 * user has authorized the use of their data against this source.
 *
 * @param source source being queried
 * @param input query request
 * @throws OAuthPluginException if the user's access token is not available or if the source is
 *     not authorized
 * @throws StopProcessingException for errors not related to OAuth
 */
@Override
public QueryRequest process(Source source, QueryRequest input) throws StopProcessingException {
    OAuthFederatedSource oauthSource = getSource(source);
    if (oauthSource == null) {
        return input;
    }
    Object securityAssertion = input.getProperties().get(SECURITY_SUBJECT);
    if (!(securityAssertion instanceof Subject)) {
        LOGGER.warn("The user's subject is not available.");
        throw new StopProcessingException("The user's subject is not available.");
    }
    Subject subject = (Subject) securityAssertion;
    Session session = subject.getSession(false);
    if (session == null) {
        LOGGER.warn("The user's session is not available.");
        throw new StopProcessingException("The user's session is not available.");
    }
    String sessionId = (String) session.getId();
    if (sessionId == null) {
        LOGGER.warn("The user's session ID is not available.");
        throw new StopProcessingException("The user's session ID is not available.");
    }
    OIDCProviderMetadata metadata;
    try {
        metadata = OIDCProviderMetadata.parse(resourceRetriever.retrieveResource(new URL(oauthSource.getOauthDiscoveryUrl())).getContent());
    } catch (OAuthServiceException | IOException | ParseException e) {
        LOGGER.error("Unable to retrieve OAuth provider's metadata for the {} source.", oauthSource.getId());
        throw new StopProcessingException("Unable to retrieve OAuth provider's metadata.");
    }
    TokenEntry tokenEntry = tokenStorage.read(sessionId, oauthSource.getId());
    if (tokenEntry == null) {
        // See if the user already logged in to the OAuth provider for a different source
        findExistingTokens(oauthSource, sessionId, metadata);
        throw createNoAuthException(oauthSource, sessionId, metadata, "the user's tokens were not found.");
    }
    // an outdated token)
    if (!oauthSource.getOauthDiscoveryUrl().equals(tokenEntry.getDiscoveryUrl())) {
        // the discoveryUrl is different from the one stored - the user must login
        tokenStorage.delete(sessionId, oauthSource.getId());
        findExistingTokens(oauthSource, sessionId, metadata);
        throw createNoAuthException(oauthSource, sessionId, metadata, "the oauth provider information has been changed and is different from the one stored.");
    }
    verifyAccessToken(oauthSource, sessionId, tokenEntry, metadata);
    return input;
}
Also used : OAuthFederatedSource(ddf.catalog.source.OAuthFederatedSource) OAuthServiceException(org.apache.cxf.rs.security.oauth2.provider.OAuthServiceException) StopProcessingException(ddf.catalog.plugin.StopProcessingException) IOException(java.io.IOException) Subject(ddf.security.Subject) URL(java.net.URL) DISCOVERY_URL(org.codice.ddf.security.token.storage.api.TokenStorage.DISCOVERY_URL) TokenEntry(org.codice.ddf.security.token.storage.api.TokenInformation.TokenEntry) OIDCProviderMetadata(com.nimbusds.openid.connect.sdk.op.OIDCProviderMetadata) ParseException(com.nimbusds.oauth2.sdk.ParseException) Session(org.apache.shiro.session.Session)

Aggregations

Session (org.apache.shiro.session.Session)93 Subject (org.apache.shiro.subject.Subject)34 Test (org.junit.Test)21 Serializable (java.io.Serializable)11 PrincipalCollection (org.apache.shiro.subject.PrincipalCollection)8 UsernamePasswordToken (org.apache.shiro.authc.UsernamePasswordToken)6 RequestMapping (org.springframework.web.bind.annotation.RequestMapping)6 SecurityManager (org.apache.shiro.mgt.SecurityManager)5 SessionListener (org.apache.shiro.session.SessionListener)5 ResponseBody (org.springframework.web.bind.annotation.ResponseBody)5 User (com.hfut.entity.User)4 Subject (ddf.security.Subject)4 ApiOperation (io.swagger.annotations.ApiOperation)4 Date (java.util.Date)4 HttpServletRequest (javax.servlet.http.HttpServletRequest)4 AuthenticationException (org.apache.shiro.authc.AuthenticationException)4 InvalidSessionException (org.apache.shiro.session.InvalidSessionException)4 SessionListenerAdapter (org.apache.shiro.session.SessionListenerAdapter)4 ArrayList (java.util.ArrayList)3 HashMap (java.util.HashMap)3