Search in sources :

Example 1 with Account

use of io.undertow.security.idm.Account in project wildfly by wildfly.

the class LogoutSessionListener method sessionDestroyed.

@Override
public void sessionDestroyed(HttpSessionEvent se) {
    //we need to get the current account
    //there are two options here, we can look for the account in the current request
    //or we can look for the account that has been saved in the session
    //for maximum compatibility we do both
    ServletRequestContext src = ServletRequestContext.current();
    Account requestAccount = null;
    if (src != null) {
        requestAccount = src.getExchange().getSecurityContext().getAuthenticatedAccount();
        if (requestAccount != null) {
            clearAccount(requestAccount);
        }
    }
    if (se.getSession() instanceof HttpSessionImpl) {
        final HttpSessionImpl impl = (HttpSessionImpl) se.getSession();
        Session session;
        if (WildFlySecurityManager.isChecking()) {
            session = WildFlySecurityManager.doChecked(new PrivilegedAction<Session>() {

                @Override
                public Session run() {
                    return impl.getSession();
                }
            });
        } else {
            session = impl.getSession();
        }
        if (session != null) {
            AuthenticatedSessionManager.AuthenticatedSession authenticatedSession = (AuthenticatedSessionManager.AuthenticatedSession) session.getAttribute(CachedAuthenticatedSessionHandler.class.getName() + ".AuthenticatedSession");
            if (authenticatedSession != null) {
                Account sessionAccount = authenticatedSession.getAccount();
                if (sessionAccount != null && !sessionAccount.equals(requestAccount)) {
                    clearAccount(sessionAccount);
                }
            }
        }
    }
}
Also used : Account(io.undertow.security.idm.Account) CachedAuthenticatedSessionHandler(io.undertow.servlet.handlers.security.CachedAuthenticatedSessionHandler) HttpSessionImpl(io.undertow.servlet.spec.HttpSessionImpl) PrivilegedAction(java.security.PrivilegedAction) ServletRequestContext(io.undertow.servlet.handlers.ServletRequestContext) AuthenticatedSessionManager(io.undertow.security.api.AuthenticatedSessionManager) Session(io.undertow.server.session.Session)

Example 2 with Account

use of io.undertow.security.idm.Account in project wildfly by wildfly.

the class DigestAuthenticationMechanism method handleDigestHeader.

public AuthenticationMechanismOutcome handleDigestHeader(HttpServerExchange exchange, final SecurityContext securityContext) {
    DigestContext context = exchange.getAttachment(DigestContext.ATTACHMENT_KEY);
    Map<DigestAuthorizationToken, String> parsedHeader = context.getParsedHeader();
    // Step 1 - Verify the set of tokens received to ensure valid values.
    Set<DigestAuthorizationToken> mandatoryTokens = new HashSet<>(MANDATORY_REQUEST_TOKENS);
    if (!supportedAlgorithms.contains(DigestAlgorithm.MD5)) {
        // If we don't support MD5 then the client must choose an algorithm as we can not fall back to MD5.
        mandatoryTokens.add(DigestAuthorizationToken.ALGORITHM);
    }
    if (!supportedQops.isEmpty() && !supportedQops.contains(DigestQop.AUTH)) {
        // If we do not support auth then we are mandating auth-int so force the client to send a QOP
        mandatoryTokens.add(DigestAuthorizationToken.MESSAGE_QOP);
    }
    DigestQop qop = null;
    // This check is early as is increases the list of mandatory tokens.
    if (parsedHeader.containsKey(DigestAuthorizationToken.MESSAGE_QOP)) {
        qop = DigestQop.forName(parsedHeader.get(DigestAuthorizationToken.MESSAGE_QOP));
        if (qop == null || !supportedQops.contains(qop)) {
            // We are also ensuring the client is not trying to force a qop that has been disabled.
            REQUEST_LOGGER.invalidTokenReceived(DigestAuthorizationToken.MESSAGE_QOP.getName(), parsedHeader.get(DigestAuthorizationToken.MESSAGE_QOP));
            // TODO - This actually needs to result in a HTTP 400 Bad Request response and not a new challenge.
            return AuthenticationMechanismOutcome.NOT_AUTHENTICATED;
        }
        context.setQop(qop);
        mandatoryTokens.add(DigestAuthorizationToken.CNONCE);
        mandatoryTokens.add(DigestAuthorizationToken.NONCE_COUNT);
    }
    // Check all mandatory tokens are present.
    mandatoryTokens.removeAll(parsedHeader.keySet());
    if (mandatoryTokens.size() > 0) {
        for (DigestAuthorizationToken currentToken : mandatoryTokens) {
            // TODO - Need a better check and possible concatenate the list of tokens - however
            // even having one missing token is not something we should routinely expect.
            REQUEST_LOGGER.missingAuthorizationToken(currentToken.getName());
        }
        // TODO - This actually needs to result in a HTTP 400 Bad Request response and not a new challenge.
        return AuthenticationMechanismOutcome.NOT_AUTHENTICATED;
    }
    // Perform some validation of the remaining tokens.
    if (!realmName.equals(parsedHeader.get(DigestAuthorizationToken.REALM))) {
        REQUEST_LOGGER.invalidTokenReceived(DigestAuthorizationToken.REALM.getName(), parsedHeader.get(DigestAuthorizationToken.REALM));
        // TODO - This actually needs to result in a HTTP 400 Bad Request response and not a new challenge.
        return AuthenticationMechanismOutcome.NOT_AUTHENTICATED;
    }
    if (parsedHeader.containsKey(DigestAuthorizationToken.OPAQUE)) {
        if (!OPAQUE_VALUE.equals(parsedHeader.get(DigestAuthorizationToken.OPAQUE))) {
            REQUEST_LOGGER.invalidTokenReceived(DigestAuthorizationToken.OPAQUE.getName(), parsedHeader.get(DigestAuthorizationToken.OPAQUE));
            return AuthenticationMechanismOutcome.NOT_AUTHENTICATED;
        }
    }
    DigestAlgorithm algorithm;
    if (parsedHeader.containsKey(DigestAuthorizationToken.ALGORITHM)) {
        algorithm = DigestAlgorithm.forName(parsedHeader.get(DigestAuthorizationToken.ALGORITHM));
        if (algorithm == null || !supportedAlgorithms.contains(algorithm)) {
            // We are also ensuring the client is not trying to force an algorithm that has been disabled.
            REQUEST_LOGGER.invalidTokenReceived(DigestAuthorizationToken.ALGORITHM.getName(), parsedHeader.get(DigestAuthorizationToken.ALGORITHM));
            // TODO - This actually needs to result in a HTTP 400 Bad Request response and not a new challenge.
            return AuthenticationMechanismOutcome.NOT_AUTHENTICATED;
        }
    } else {
        // We know this is safe as the algorithm token was made mandatory
        // if MD5 is not supported.
        algorithm = DigestAlgorithm.MD5;
    }
    try {
        context.setAlgorithm(algorithm);
    } catch (NoSuchAlgorithmException e) {
        /*
             * This should not be possible in a properly configured installation.
             */
        REQUEST_LOGGER.exceptionProcessingRequest(e);
        return AuthenticationMechanismOutcome.NOT_AUTHENTICATED;
    }
    final String userName = parsedHeader.get(DigestAuthorizationToken.USERNAME);
    final IdentityManager identityManager = getIdentityManager(securityContext);
    final Account account;
    if (algorithm.isSession()) {
        /* This can follow one of the following: -
             *   1 - New session so use DigestCredentialImpl with the IdentityManager to
             *       create a new session key.
             *   2 - Obtain the existing session key from the session store and validate it, just use
             *       IdentityManager to validate account is still active and the current role assignment.
             */
        throw new IllegalStateException("Not yet implemented.");
    } else {
        final DigestCredential credential = new DigestCredentialImpl(context);
        account = identityManager.verify(userName, credential);
    }
    if (account == null) {
        // Authentication has failed, this could either be caused by the user not-existing or it
        // could be caused due to an invalid hash.
        securityContext.authenticationFailed(MESSAGES.authenticationFailed(userName), mechanismName);
        return AuthenticationMechanismOutcome.NOT_AUTHENTICATED;
    }
    // Step 3 - Verify that the nonce was eligible to be used.
    if (!validateNonceUse(context, parsedHeader, exchange)) {
        // TODO - This is the right place to make use of the decision but the check needs to be much much sooner
        // otherwise a failure server
        // side could leave a packet that could be 're-played' after the failed auth.
        // The username and password verification passed but for some reason we do not like the nonce.
        context.markStale();
        // can easily hit this point.
        return AuthenticationMechanismOutcome.NOT_AUTHENTICATED;
    }
    // We have authenticated the remote user.
    //sendAuthenticationInfoHeader(exchange);
    securityContext.authenticationComplete(account, mechanismName, true);
    return AuthenticationMechanismOutcome.AUTHENTICATED;
// Step 4 - Set up any QOP related requirements.
// TODO - Do QOP
}
Also used : DigestAuthorizationToken(io.undertow.security.impl.DigestAuthorizationToken) DigestQop(io.undertow.security.impl.DigestQop) Account(io.undertow.security.idm.Account) IdentityManager(io.undertow.security.idm.IdentityManager) NoSuchAlgorithmException(java.security.NoSuchAlgorithmException) HashSet(java.util.HashSet) DigestAlgorithm(io.undertow.security.idm.DigestAlgorithm)

Example 3 with Account

use of io.undertow.security.idm.Account in project wildfly by wildfly.

the class AuditNotificationReceiver method handleNotification.

@Override
public void handleNotification(SecurityNotification notification) {
    EventType event = notification.getEventType();
    if (event == EventType.AUTHENTICATED || event == EventType.FAILED_AUTHENTICATION) {
        AuditEvent auditEvent = new AuditEvent(event == EventType.AUTHENTICATED ? AuditLevel.SUCCESS : AuditLevel.FAILURE);
        Map<String, Object> ctxMap = new HashMap<String, Object>();
        Account account = notification.getAccount();
        if (account != null) {
            ctxMap.put("principal", account.getPrincipal().getName());
        }
        ctxMap.put("message", notification.getMessage());
        ServletRequestContext src = notification.getExchange().getAttachment(ServletRequestContext.ATTACHMENT_KEY);
        if (src != null) {
            ServletRequest hsr = src.getServletRequest();
            if (hsr instanceof HttpServletRequest) {
                ctxMap.put("request", WebUtil.deriveUsefulInfo((HttpServletRequest) hsr));
            }
        }
        ctxMap.put("Source", getClass().getCanonicalName());
        auditEvent.setContextMap(ctxMap);
        auditManager.audit(auditEvent);
    }
}
Also used : HttpServletRequest(javax.servlet.http.HttpServletRequest) Account(io.undertow.security.idm.Account) ServletRequest(javax.servlet.ServletRequest) HttpServletRequest(javax.servlet.http.HttpServletRequest) EventType(io.undertow.security.api.SecurityNotification.EventType) HashMap(java.util.HashMap) ServletRequestContext(io.undertow.servlet.handlers.ServletRequestContext) AuditEvent(org.jboss.security.audit.AuditEvent)

Example 4 with Account

use of io.undertow.security.idm.Account in project wildfly by wildfly.

the class LogoutNotificationReceiver method handleNotification.

@Override
public void handleNotification(SecurityNotification notification) {
    if (notification.getEventType() == SecurityNotification.EventType.LOGGED_OUT) {
        Account account = notification.getAccount();
        Principal principal = (account instanceof AccountImpl) ? ((AccountImpl) account).getOriginalPrincipal() : account.getPrincipal();
        if (principal != null) {
            // perform the logout of the principal using the subject currently set in the security context.
            Subject subject = SecurityActions.getSubject();
            this.manager.logout(principal, subject);
        }
        // Clear old context
        SecurityActions.clearSecurityContext();
        SecurityActions.setSecurityRoles(null);
        // Set a new one in case re-authentication is done within the same thread
        org.jboss.security.SecurityContext securityContext = SecurityActions.createSecurityContext(securityDomain);
        notification.getExchange().putAttachment(UndertowSecurityAttachments.SECURITY_CONTEXT_ATTACHMENT, securityContext);
        SecurityActions.setSecurityContextOnAssociation(securityContext);
    }
}
Also used : Account(io.undertow.security.idm.Account) Principal(java.security.Principal) Subject(javax.security.auth.Subject)

Example 5 with Account

use of io.undertow.security.idm.Account in project wildfly by wildfly.

the class DistributableSingleSignOnTestCase method getAccount.

@Test
public void getAccount() {
    BatchContext context = mock(BatchContext.class);
    Account account = mock(Account.class);
    String mechanism = HttpServletRequest.BASIC_AUTH;
    AuthenticatedSession authentication = new AuthenticatedSession(account, mechanism);
    when(this.batcher.resumeBatch(this.batch)).thenReturn(context);
    when(this.sso.getAuthentication()).thenReturn(authentication);
    Account result = this.subject.getAccount();
    assertSame(account, result);
    verifyZeroInteractions(this.batch);
    verify(context).close();
}
Also used : Account(io.undertow.security.idm.Account) AuthenticatedSession(io.undertow.security.api.AuthenticatedSessionManager.AuthenticatedSession) BatchContext(org.wildfly.clustering.ee.BatchContext) Test(org.junit.Test)

Aggregations

Account (io.undertow.security.idm.Account)28 IdentityManager (io.undertow.security.idm.IdentityManager)8 AuthenticatedSession (io.undertow.security.api.AuthenticatedSessionManager.AuthenticatedSession)6 Test (org.junit.Test)6 PasswordCredential (io.undertow.security.idm.PasswordCredential)5 HashMap (java.util.HashMap)5 BatchContext (org.wildfly.clustering.ee.BatchContext)5 SecurityContext (io.undertow.security.api.SecurityContext)4 ServletRequestContext (io.undertow.servlet.handlers.ServletRequestContext)4 CachedAuthenticatedSessionHandler (io.undertow.servlet.handlers.security.CachedAuthenticatedSessionHandler)4 Map (java.util.Map)4 Batch (org.wildfly.clustering.ee.Batch)4 Credential (io.undertow.security.idm.Credential)3 IOException (java.io.IOException)3 AuthenticatedSessionManager (io.undertow.security.api.AuthenticatedSessionManager)2 DigestAlgorithm (io.undertow.security.idm.DigestAlgorithm)2 Session (io.undertow.server.session.Session)2 HttpString (io.undertow.util.HttpString)2 ByteBuffer (java.nio.ByteBuffer)2 NoSuchAlgorithmException (java.security.NoSuchAlgorithmException)2