2016-03-14 41 views
0

我正在嘗試使用JWT使用Angular作爲我的前端和Spring作爲後端進行身份驗證。我有以下AuthenticationFilter類設置JWT過濾器:使用JWT和Spring登錄失敗

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類在登錄檢查和設置驗證頭髮生:

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異常拋出爲「Missing or invalid Authorization header」。

我也配置我的應用程序在鏈下面添加此過濾器:

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

「授權」 頭被拼寫錯誤:

替換來自:

String authHeader = ((HttpServletRequest) request).getHeader("Authorizatoin"); 

要:

String authHeader = ((HttpServletRequest) request).getHeader("Authorization"); 

您可以考慮使用Spring框架常數爲HTTP標頭,以避免這樣的問題:

String authHeader = ((HttpServletRequest) request).getHeader(org.springframework.http.HttpHeaders.AUTHORIZATION); 
+0

謝謝邁克爾!我改變了拼寫,但仍然有同樣的問題。該請求未到達UserController類。 (另外,我在Eclipse上進行了Maven更新以刷新上下文)。 – St1id3r

+0

你有什麼錯誤嗎? –

+0

我在啓動項目時沒有任何錯誤,但是隻要表單嘗試到達登錄模塊就會發生這種情況。 SEVERE:在路徑[/ febatlas]上下文中,servlet [dispatcher]的Servlet.service()引發了異常[Missing or invalid Authorization header。],其根本原因爲 javax.servlet.ServletException:缺少或無效的授權標頭。 – St1id3r