use of org.codice.ddf.platform.filter.AuthenticationException in project ddf by codice.
the class LoginFilter method doFilter.
/**
* Gets token, resolves token references, and calls the security manager to get a Subject
*
* @param request
* @param response
* @param chain
* @throws IOException
* @throws ServletException
*/
@Override
public void doFilter(final ServletRequest request, final ServletResponse response, final SecurityFilterChain chain) throws IOException, AuthenticationException {
LOGGER.debug("Performing doFilter() on LoginFilter");
HttpServletRequest httpRequest = (HttpServletRequest) request;
// Skip filter if no authentication policy
if (request.getAttribute(ContextPolicy.NO_AUTH_POLICY) != null) {
LOGGER.debug("NO_AUTH_POLICY header was found, skipping login filter.");
chain.doFilter(request, response);
return;
}
// grab token from httpRequest
BaseAuthenticationToken token;
Object ddfAuthToken = httpRequest.getAttribute(AUTHENTICATION_TOKEN_KEY);
if (ddfAuthToken instanceof HandlerResult && ((HandlerResult) ddfAuthToken).getToken() instanceof BaseAuthenticationToken) {
token = (BaseAuthenticationToken) ((HandlerResult) ddfAuthToken).getToken();
} else {
LOGGER.debug("Could not attach subject to http request.");
return;
}
token.setX509Certs((X509Certificate[]) httpRequest.getAttribute("javax.servlet.request.X509Certificate"));
token.setRequestURI(httpRequest.getRequestURI());
if (securityManager == null) {
throw new AuthenticationException("Unable to authenticate user, system is not available.");
}
// get subject from the token
Subject subject;
try {
subject = securityManager.getSubject(token);
} catch (SecurityServiceException e) {
LOGGER.debug("Error getting subject from a Shiro realm", e);
return;
}
// check that security manager was able to resolve a subject
if (subject == null) {
LOGGER.debug("Could not attach subject to http request.");
return;
}
// subject is now resolved, perform request as that subject
httpRequest.setAttribute(SecurityConstants.SECURITY_SUBJECT, subject);
LOGGER.debug("Now performing request as user {} for {}", subject.getPrincipal(), StringUtils.isNotBlank(httpRequest.getContextPath()) ? httpRequest.getContextPath() : httpRequest.getServletPath());
subject.execute(() -> {
// attach subject to the http session
if (contextPolicyManager.getSessionAccess()) {
addToSession(httpRequest, subject);
}
PrivilegedExceptionAction<Void> action = () -> {
chain.doFilter(request, response);
return null;
};
Collection<SecurityAssertion> securityAssertions = subject.getPrincipals().byType(SecurityAssertion.class);
if (!securityAssertions.isEmpty()) {
HashSet<?> emptySet = new HashSet<>();
javax.security.auth.Subject javaSubject = new javax.security.auth.Subject(true, securityAssertions.stream().map(SecurityAssertion::getPrincipals).flatMap(Collection::stream).collect(Collectors.toSet()), emptySet, emptySet);
httpRequest.setAttribute(SecurityConstants.SECURITY_JAVA_SUBJECT, javaSubject);
if (contextPolicyManager.getSessionAccess()) {
addToSession(httpRequest, javaSubject);
}
javax.security.auth.Subject.doAs(javaSubject, action);
} else {
LOGGER.debug("Subject had no security assertion.");
}
return null;
});
}
use of org.codice.ddf.platform.filter.AuthenticationException in project ddf by codice.
the class WebSSOFilter method handleRequest.
private void handleRequest(HttpServletRequest httpRequest, HttpServletResponse httpResponse, SecurityFilterChain filterChain, List<AuthenticationHandler> handlers) throws AuthenticationException, IOException {
HandlerResult result = null;
// First pass, see if anyone can come up with proper security token from the get-go
LOGGER.debug("Checking for existing tokens in request.");
final String path = httpRequest.getRequestURI();
String ipAddress = httpRequest.getHeader("X-FORWARDED-FOR");
if (ipAddress == null) {
ipAddress = httpRequest.getRemoteAddr();
}
if (contextPolicyManager.getSessionAccess()) {
result = checkForPreviousResultOnSession(httpRequest, ipAddress);
}
// no result found on session, try and get result from handlers
if (result == null) {
if (!handlers.isEmpty()) {
result = getResultFromHandlers(httpRequest, httpResponse, filterChain, handlers);
} else {
// no configured handlers
if (contextPolicyManager.getGuestAccess()) {
LOGGER.trace("No configured handlers found, but guest access is enabled. Continuing with an empty handler result for guest login.");
result = new HandlerResultImpl(Status.NO_ACTION, null);
result.setSource("default");
} else {
LOGGER.warn("No configured handler found and guest access is disabled. Returning status code 503, Service Unavailable. Check system configuration and bundle state.");
returnSimpleResponse(HttpServletResponse.SC_SERVICE_UNAVAILABLE, httpResponse);
return;
}
}
}
handleResultStatus(httpRequest, httpResponse, result, path, ipAddress);
// If we got here, we've received our tokens to continue
LOGGER.debug("Invoking the rest of the filter chain");
try {
filterChain.doFilter(httpRequest, httpResponse);
} catch (Exception e) {
LOGGER.debug("Exception in filter chain - passing off to handlers. Msg: {}", e.getMessage(), e);
// First pass, see if anyone can come up with proper security token
// from the git-go
result = null;
for (AuthenticationHandler auth : handlers) {
result = auth.handleError(httpRequest, httpResponse, filterChain);
if (result.getStatus() != HandlerResult.Status.NO_ACTION) {
LOGGER.debug("Handler {} set the status to {}", auth.getAuthenticationType(), result.getStatus());
break;
}
}
if (result == null || result.getStatus() == HandlerResult.Status.NO_ACTION) {
LOGGER.debug("Error during authentication - no error recovery attempted - returning bad request.");
httpResponse.setStatus(HttpServletResponse.SC_BAD_REQUEST);
httpResponse.sendError(HttpServletResponse.SC_BAD_REQUEST);
httpResponse.flushBuffer();
}
throw new AuthenticationFailureException(e);
}
}
use of org.codice.ddf.platform.filter.AuthenticationException in project ddf by codice.
the class AuthorizationFilter method doFilter.
@SuppressWarnings("PackageAccessibility")
@Override
public void doFilter(ServletRequest request, ServletResponse response, SecurityFilterChain chain) throws IOException, AuthenticationException {
HttpServletRequest httpRequest = (HttpServletRequest) request;
HttpServletResponse httpResponse = (HttpServletResponse) response;
Subject subject = null;
if (request.getAttribute(ContextPolicy.NO_AUTH_POLICY) != null) {
LOGGER.debug("NO_AUTH_POLICY header was found, skipping authorization filter.");
chain.doFilter(request, response);
} else {
try {
subject = SecurityUtils.getSubject();
} catch (Exception e) {
LOGGER.debug("Unable to retrieve user from request.", e);
}
boolean permitted = true;
final String path = httpRequest.getRequestURI();
ContextPolicy policy = contextPolicyManager.getContextPolicy(path);
CollectionPermission permissions = null;
if (policy != null && subject != null) {
permissions = policy.getAllowedAttributePermissions();
if (!permissions.isEmpty()) {
permitted = subject.isPermitted(permissions);
}
} else {
LOGGER.warn("Unable to determine policy for path {}. User is not permitted to continue. Check policy configuration!", LogSanitizer.sanitize(path));
permitted = false;
}
if (!permitted) {
securityLogger.audit("Subject not authorized to view resource {}", path);
LOGGER.debug("Subject not authorized.");
returnNotAuthorized(httpResponse);
} else {
if (!permissions.isEmpty()) {
securityLogger.audit("Subject is authorized to view resource {}", path);
}
LOGGER.debug("Subject is authorized!");
chain.doFilter(request, response);
}
}
}
use of org.codice.ddf.platform.filter.AuthenticationException in project ddf by codice.
the class AuthorizationFilterTest method testNoSubject.
@Test
public void testNoSubject() {
ContextPolicyManager contextPolicyManager = new TestPolicyManager();
contextPolicyManager.setContextPolicy(PATH, getMockContextPolicy());
AuthorizationFilter loginFilter = new AuthorizationFilter(contextPolicyManager);
loginFilter.setSecurityLogger(mock(SecurityLogger.class));
loginFilter.init();
HttpServletRequest servletRequest = getMockServletRequest();
HttpServletResponse servletResponse = mock(HttpServletResponse.class);
SecurityFilterChain filterChain = (request, response) -> fail("Should not have called doFilter without a valid Subject");
try {
loginFilter.doFilter(servletRequest, servletResponse, filterChain);
} catch (IOException | AuthenticationException e) {
fail(e.getMessage());
}
}
use of org.codice.ddf.platform.filter.AuthenticationException in project ddf by codice.
the class AuthorizationFilterTest method testUnAuthorizedSubject.
@Test
public void testUnAuthorizedSubject() {
ContextPolicyManager contextPolicyManager = new TestPolicyManager();
contextPolicyManager.setContextPolicy(PATH, getMockContextPolicy());
AuthorizationFilter loginFilter = new AuthorizationFilter(contextPolicyManager);
loginFilter.setSecurityLogger(mock(SecurityLogger.class));
loginFilter.init();
Subject subject = mock(Subject.class);
when(subject.isPermitted(any(CollectionPermission.class))).thenReturn(false);
ThreadContext.bind(subject);
HttpServletRequest servletRequest = getMockServletRequest();
HttpServletResponse servletResponse = mock(HttpServletResponse.class);
SecurityFilterChain filterChain = (request, response) -> fail("Should not have called doFilter without a valid Subject");
try {
loginFilter.doFilter(servletRequest, servletResponse, filterChain);
} catch (IOException | AuthenticationException e) {
fail(e.getMessage());
}
ThreadContext.unbindSubject();
}
Aggregations