我正在尝试使用JWT(使用Angular作为我的前端,并使用Spring作为后端)来设置身份验证。我具有以下用于设置JWT过滤器的AuthenticationFilter类:
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;
}
}
我在这里缺少一些配置还是犯了一些严重的错误?任何帮助,不胜感激!
“授权”标头的拼写错误:
从以下位置替换:
String authHeader = ((HttpServletRequest) request).getHeader("Authorizatoin");
至:
String authHeader = ((HttpServletRequest) request).getHeader("Authorization");
您可以考虑将Spring Framework常量用于http标头,以避免出现此类问题:
String authHeader = ((HttpServletRequest) request).getHeader(org.springframework.http.HttpHeaders.AUTHORIZATION);
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句