I have a REST api developed using SpringBoot and it contains the implementation for JWT for authentication and authorization. A FilterRegistrationBean
is used for that.
I have a class called JwtFilter
which extends GenericFilterBean
. In that I look for the content of the request headers in order to authorize the users.
public class JwtFilter extends GenericFilterBean{
@Override
public void doFilter(final ServletRequest req, final ServletResponse res, final FilterChain chain) throws IOException, ServletException {
System.out.println("INSIDE JWT FILTER");
final HttpServletRequest request = (HttpServletRequest) req;
final String authHeader = request.getHeader("Authorization");
String reqHdr = request.getHeader("X-Requested-By");
String myHdr = request.getHeader("myheader");
System.out.println("Auth header = "+authHeader);
System.out.println("requested by header = "+reqHdr);
System.out.println("my header = "+myHdr);
if (authHeader == null || !authHeader.startsWith("Bearer ")) {
System.out.println("JwtFilter.doFilter -> auth header is null or token does not start with Bearer");
throw new ServletException("Missing or invalid Authorization header.");
}
final String token = authHeader.substring(7); // The part after "Bearer "
try {
final Claims claims = Jwts.parser().setSigningKey("secretkey").parseClaimsJws(token).getBody();
request.setAttribute("claims", claims);
}
catch (final SignatureException e) {
System.out.println("VIRGLK EXCEPTION : JwtFilter.doFilter -> Signature Exception, invalid token = "+e.getMessage());
throw new ServletException("Invalid token.");
}
chain.doFilter(req, res);
}
}
I can assure that setting the headers dynamically works fine, since I tested it for some other HTTP requests to the same server which are not url filtered(login request).
But, when it comes to the requests which are filtered by above class, I see that every header of the requests are null.
Given below is how I add headers in to the requests in Angular2. I have extended BaserequestOptions
class and overridden the merge method in order to add headers dynamically.
@Injectable()
export class CustomRequestOptions extends BaseRequestOptions {
constructor(private _globals: Globals) {
super();
this.headers.set('Content-Type', 'application/json');
this.headers.set('X-Requested-By', 'Angular 2');
}
merge(options?: RequestOptionsArgs): RequestOptions {
var newOptions = super.merge(options);
let hdr = this._globals.getAuthorization();
newOptions.headers.set("Authorization", hdr);
newOptions.headers.set("myheader", "my header value");
return newOptions;
}
}
But these headers are null when checked in the API for the requests which are filtered. As I mentioned above, there is no problem for the non filtered requests. Both statically appended('X-Requested-By') and dynamically appended('myheader') headers and available in the server.
I cannot understand what is happening here. At least, I have no clue, from which side, the error is coming from.
Following is the request header copied from browser console for the failed request.
OPTIONS /protected/get-roles/USER HTTP/1.1
Host: 127.0.0.1:8080
Connection: keep-alive
Access-Control-Request-Method: GET
Origin: http://localhost:3000
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.133 Safari/537.36
Access-Control-Request-Headers: authorization,content-type,myheader,x-requested-by
Accept: */*
Can someone point me out what could be the issue here. I am clueless.
EDIT
I guess the issue is coming from the server because of the following reason.
I was able to successfully retrieve all the header values of a request which was done after the authorization header is set and that request is not a filtered one. Therefore I guess, there is something wrong with the JWT Filter implementation.
This might be a stupid question, but, Is it due to the reason that the requests I send are not in the type of ServletRequest
may be? doFilter
method in JwtFilter
accepts the parameter of ServletRequest
.