1 package com.atlassian.asap.core.server.filter;
2
3 import com.atlassian.asap.api.Jwt;
4 import com.atlassian.asap.api.exception.AuthenticationFailedException;
5 import com.atlassian.asap.api.exception.TransientAuthenticationFailedException;
6 import com.atlassian.asap.api.server.http.RequestAuthenticator;
7 import com.atlassian.asap.core.JwtConstants;
8 import com.google.common.base.Preconditions;
9 import org.apache.commons.lang3.StringUtils;
10 import org.apache.http.HttpHeaders;
11 import org.apache.http.HttpStatus;
12 import org.slf4j.Logger;
13 import org.slf4j.LoggerFactory;
14
15 import javax.servlet.Filter;
16 import javax.servlet.FilterChain;
17 import javax.servlet.FilterConfig;
18 import javax.servlet.ServletException;
19 import javax.servlet.ServletRequest;
20 import javax.servlet.ServletResponse;
21 import javax.servlet.http.HttpServletRequest;
22 import javax.servlet.http.HttpServletResponse;
23 import java.io.IOException;
24
25
26
27
28
29 public abstract class AbstractRequestAuthenticationFilter implements Filter {
30
31
32
33
34 public static final String AUTHENTIC_JWT_REQUEST_ATTRIBUTE = "asap.authentic.jwt";
35
36 private static final Logger logger = LoggerFactory.getLogger(AbstractRequestAuthenticationFilter.class);
37
38 private RequestAuthenticator requestAuthenticator;
39
40 @Override
41 public void init(FilterConfig filterConfig) throws ServletException {
42 requestAuthenticator = getRequestAuthenticator(filterConfig);
43 }
44
45 @Override
46 public final void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
47 throws IOException, ServletException {
48 Preconditions.checkState(requestAuthenticator != null, "Filter has not been initialized");
49
50
51 HttpServletRequest httpRequest = (HttpServletRequest) request;
52 HttpServletResponse httpResponse = (HttpServletResponse) response;
53
54 String authorizationHeader = httpRequest.getHeader(HttpHeaders.AUTHORIZATION);
55 if (StringUtils.isBlank(authorizationHeader)) {
56
57 logger.debug("Request rejected because JWT token cannot be found");
58 onAuthenticationFailure(httpRequest, httpResponse, chain);
59 } else {
60 try {
61 Jwt authenticJwt = requestAuthenticator.authenticateRequest(authorizationHeader);
62 logger.trace("Accepting authentic token with identifier {}", authenticJwt.getClaims().getJwtId());
63 saveToken(request, authenticJwt);
64 onAuthenticationSuccess(authenticJwt, httpRequest, httpResponse, chain);
65 } catch (TransientAuthenticationFailedException e) {
66
67 logger.debug("Request rejected because JWT token could not be verified at this time", e);
68 onAuthenticationError(httpRequest, httpResponse, chain, e);
69 } catch (AuthenticationFailedException e) {
70
71 logger.debug("Request rejected because JWT token cannot be verified", e);
72 onAuthenticationFailure(httpRequest, httpResponse, chain);
73 }
74 }
75 }
76
77
78
79
80
81 protected void saveToken(ServletRequest request, Jwt authenticJwt) {
82 request.setAttribute(AUTHENTIC_JWT_REQUEST_ATTRIBUTE, authenticJwt);
83 }
84
85
86
87
88
89 protected void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
90 throws IOException, ServletException {
91 response.sendError(HttpStatus.SC_UNAUTHORIZED);
92 response.setHeader(HttpHeaders.WWW_AUTHENTICATE, JwtConstants.BEARER_AUTHENTICATION_SCHEME);
93 }
94
95
96
97
98
99 protected void onAuthenticationError(HttpServletRequest request, HttpServletResponse response, FilterChain chain, TransientAuthenticationFailedException e)
100 throws IOException, ServletException {
101
102 logger.error("An error occurred while authenticating this request", e);
103 response.sendError(HttpStatus.SC_SERVICE_UNAVAILABLE);
104 }
105
106
107
108
109
110
111
112 protected void onAuthenticationSuccess(Jwt authenticJwt, HttpServletRequest request, HttpServletResponse response, FilterChain chain)
113 throws IOException, ServletException {
114 chain.doFilter(request, response);
115 }
116
117 @Override
118 public void destroy() {
119
120 }
121
122
123
124
125 protected abstract RequestAuthenticator getRequestAuthenticator(FilterConfig filterConfig);
126 }