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);
}
}
}
}
}
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
}
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);
}
}
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);
}
}
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();
}
Aggregations