Reputation: 41919
Using a custom Spring Security filter, I'd like to return an HTTP 401 error code if the HTTP Header doesn't contain a particular key-value pair.
Example:
public void doFilter(ServletRequest req, ServletResponse res,
FilterChain chain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) req;
final String val = request.getHeader(FOO_TOKEN)
if(val == null || !val.equals("FOO")) {
// token is not valid, return an HTTP 401 error code
...
}
else {
// token is good, let it proceed
chain.doFilter(req, res);
}
As I understand, I could do the following:
(1) ((HttpServletResponse) res).setStatus(401)
and skip the remaining filter chain
OR
(2) throw an exception that, eventually, results in Spring Security throwing a 401 error to the client.
If #1 is the better option, how can I skip the filter chain after calling setStatus(401)
on the response?
Or, if #2 is the right way to go, which exception should I throw?
Upvotes: 57
Views: 61503
Reputation: 11
I find this solution cleaner
public void doFilter(ServletRequest req, ServletResponse res,
FilterChain chain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) req;
final String val = request.getHeader(FOO_TOKEN)
if(val != null && val.equals("FOO")) {
// token is good, let it proceed
chain.doFilter(req, res);
return;
}
((HttpServletResponse) res).setSatatus(HttpStatus.UNAUTHORIZED.value());
}
so just set the response status code to 401 without invoking chain.doFilter when the token is not valid.
Upvotes: 0
Reputation: 116
Just do as they say in the upper answer. "so setting the response status code and returning immediately" This is just type:
res.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
Upvotes: 7
Reputation: 41
I have a similar issue. Since I implemented OAuth2, I cannot return all errors as response to the Client. Some exceptions are difficult to catch.
res.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
return;
This was the only solution working for me so far.
I have to use it on MalformedJwtException and SignatureException, because if I use response.sendError() , it does not work and calling it a second time throws another error.
Upvotes: 2
Reputation: 124
So you can use something like this.
@Override
public void doFilter() {
if (whiteListOrigins.contains(incomeOrigin)) {
httpResponse.setHeader("Access-Control-Allow-Origin", incomeOrigin);
chain.doFilter(request, response);
} else {
((HttpServletResponse) response).sendError(HttpServletResponse.SC_FORBIDDEN, "Not Allowed to Access. Please try with valid Origin.");
}
}
Upvotes: 5
Reputation: 1137
I suggest this solution below.
public void doFilter(ServletRequest req, ServletResponse res,
FilterChain chain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) req;
final String val = request.getHeader(FOO_TOKEN)
if (val == null || !val.equals("FOO")) {
((HttpServletResponse) response).sendError(HttpServletResponse.SC_UNAUTHORIZED, "The token is not valid.");
} else {
chain.doFilter(req, res);
}
}
Upvotes: 55
Reputation: 22752
From the API docs for the doFilter
method, you can:
so setting the response status code and returning immediately without invoking chain.doFilter
is the best option for what you want to achieve here.
Upvotes: 54