我正在尝试使用JWT设置身份验证,使用Angular作为我的前端,Spring作为后端。我有以下 AuthenticationFilter 类来设置JWT过滤器:
package com.atlas.config;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureException;
public class AuthenticationFilter implements Filter {
@Override
public void destroy() {
// TODO Auto-generated method stub
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
//System.out.println("filter");
HttpServletRequest req = (HttpServletRequest) request;
HttpServletResponse res = (HttpServletResponse) response;
String authHeader = ((HttpServletRequest) request).getHeader("Authorizatoin");
//System.out.println(authHeader);
if (authHeader == null || !authHeader.startsWith("Bearer ")) {
throw new ServletException("Missing or invalid Authorization header.");
}
String token = authHeader.substring(7);
try
{
//security key needs to be changed before deployment
Claims claims = Jwts.parser().setSigningKey("feb1atlaskey").parseClaimsJws(token).getBody();
req.setAttribute("claims", claims);
}
catch(SignatureException e)
{
throw new ServletException("Not a valid token");
}
chain.doFilter(req,res);
}
@Override
public void init(FilterConfig arg0) throws ServletException {
// TODO Auto-generated method stub
}
}
这是我的UserController类,其中登录检查和设置Auth标题发生:
package com.atlas.controller;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.servlet.ServletException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import com.atlas.entity.User;
import com.atlas.service.UserService;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
@RestController
@RequestMapping("/users")
public class UserController {
private final Map<String, List<String>> userDb = new HashMap<>();
public UserController() {
userDb.put("tom", Arrays.asList("user"));
userDb.put("sally", Arrays.asList("user", "admin"));
}
@RequestMapping(value = "login", method = RequestMethod.POST)
public LoginResponse login(@RequestBody final UserLogin login)
throws ServletException {
System.out.println("In user controller");
if (login.name == null || !userDb.containsKey(login.name)) {
throw new ServletException("Invalid login");
}
return new LoginResponse(Jwts.builder().setSubject(login.name)
.claim("roles", userDb.get(login.name)).setIssuedAt(new Date())
.signWith(SignatureAlgorithm.HS256, "secretkey").compact());
}
@Autowired
private UserService userService;
@RequestMapping(method = RequestMethod.POST,
produces = MediaType.APPLICATION_JSON_VALUE,
consumes = MediaType.APPLICATION_JSON_VALUE)
public void addUser(@RequestBody User u) {
this.userService.addUser(u);
}
private static class UserLogin {
public String name;
public String password;
}
private static class LoginResponse {
public String token;
public LoginResponse(final String token) {
this.token = token;
}
}
}
现在,当我使用简单表单进行登录并使用Angular发出POST请求时,它未到达UserController。它命中过滤器并将Servlet异常抛出为“丢失或无效的授权标头”。
我还配置了我的应用以在链中添加此过滤器,如下所示:
package com.atlas.config;
import javax.servlet.Filter;
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
public class AppInit extends AbstractAnnotationConfigDispatcherServletInitializer{
@Override
protected Class<?>[] getRootConfigClasses() {
// TODO Auto-generated method stub
return new Class[]{AppConfig.class,SwaggerConfig.class,AuthenticationFilter.class};
}
@Override
protected Class<?>[] getServletConfigClasses() {
// TODO Auto-generated method stub
return null;
}
@Override
protected String[] getServletMappings() {
// TODO Auto-generated method stub
return new String[] {"/api/*"};
}
@Override
protected Filter[] getServletFilters() {
Filter [] singleton = { new CORSFilter(), new AuthenticationFilter() };
return singleton;
}
}
我在这里错过了一些配置或者犯了一些可怕的错误。 任何帮助非常感谢!
答案 0 :(得分:1)
“授权”标题拼写错误:
替换为:
String authHeader = ((HttpServletRequest) request).getHeader("Authorizatoin");
要:
String authHeader = ((HttpServletRequest) request).getHeader("Authorization");
您可以考虑对http标头使用Spring Framework常量来避免此类问题:
String authHeader = ((HttpServletRequest) request).getHeader(org.springframework.http.HttpHeaders.AUTHORIZATION);