禁止JWT身份验证

时间:2019-04-08 11:13:22

标签: java spring-boot jwt

我正在关注一个可以帮助我学习Spring-Boot的教程。到目前为止一切都很好。但是,在使用JWT进行保护时,我很挣扎。我很难解释问题的具体出处,因为我还不完全了解Spring-BootJWT的工作方式。由于某些原因,身份验证无法正常工作:

  

io.jsonwebtoken.MalformedJwtException:JWT字符串必须恰好包含2个句点字符。找到:0

以下是我认为可能涉及的不同类别:

public class AuthenticationService {
    static final long EXPIRATION_TIME = 864_000_00;
    static final String SIGNING_KEY = "SecretKey";
    static final String PREFIX = "Bearer";

    public static void addToken(HttpServletResponse res, String username) {
        String JwtToken = Jwts.builder().setSubject(username)
            .setExpiration(new Date(System.currentTimeMillis() + EXPIRATION_TIME ))
            .signWith(SignatureAlgorithm.HS512, SIGNING_KEY)
            .compact();

        res.addHeader("Authorization", PREFIX + " " + JwtToken);
        res.addHeader("Access-Control-Expose-Headers", "Authorization");
    }

   public static Authentication getAuthentication(HttpServletRequest request) {
        String token = request.getHeader("Authorization");
        if(token != null) {
            String user = Jwts.parser().setSigningKey(SIGNING_KEY)
                .parseClaimsJws(token.replace(PREFIX, "")).getBody().getSubject();

            if(user != null) {
                return new UsernamePasswordAuthenticationToken(user, null, emptyList());
            }
        }
        return null;
    }
}

凭据:

public class AccountCredentials {

    private String username;
    private String password;

    public String getUsername() {
        return username;
    }
    public void setUsername(String username) {
        this.username = username;
    }
    public String getPassword() {
        return password;
    }
    public void setPassword(String password) {
       this.password = password;
   }
}

用于登录身份验证的过滤器类:

public class LoginFilter extends AbstractAuthenticationProcessingFilter{

    protected LoginFilter(String url, AuthenticationManager authManager) {
        super(new AntPathRequestMatcher(url));
        setAuthenticationManager(authManager);
    }

    @Override
    public Authentication attemptAuthentication(HttpServletRequest req, HttpServletResponse res)
        throws AuthenticationException, IOException, ServletException {
        AccountCredentials creds = new ObjectMapper().readValue(req.getInputStream(), AccountCredentials.class);
        return getAuthenticationManager().authenticate(new UsernamePasswordAuthenticationToken(creds.getUsername(), 
            creds.getPassword(), Collections.emptyList()));
    }

    @Override
    protected void successfulAuthentication(HttpServletRequest req, HttpServletResponse res, FilterChain chain,
        Authentication auth) throws IOException, ServletException {
    // TODO Auto-generated method stub
        AuthenticationService.addToken(res, auth.getName());
    }
}

处理端点中的认证:

public class AuthenticationFilter extends GenericFilterBean {

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain)
        throws IOException, ServletException {
        Authentication authentication = AuthenticationService.getAuthentication((HttpServletRequest)request);
     SecurityContextHolder.getContext().setAuthentication(authentication);
        filterChain.doFilter(request, response);    
    }
}

最后是一个类,它定义对网址的POST方法请求。

public class SecurityConfig extends WebSecurityConfigurerAdapter{
    @Autowired
    private UserDetailServiceImpl userDetailsService;

    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userDetailsService)
        .passwordEncoder(new BCryptPasswordEncoder());
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception{        
        http.cors().and().authorizeRequests().antMatchers(HttpMethod.POST, "/login").permitAll()
        .anyRequest().authenticated().and()
        .addFilterBefore(new LoginFilter("/login", authenticationManager()), UsernamePasswordAuthenticationFilter.class)
        .addFilterBefore(new AuthenticationFilter(), UsernamePasswordAuthenticationFilter.class);
    }
}

现在使用Postman,如果我有一个POST请求使用正文“ /登录”:

{"username":"someuser", "pastword":"somepassword"}

我应该获得授权。相反,我得到了:

  

io.jsonwebtoken.MalformedJwtException:JWT字符串必须恰好包含2个句点字符。找到:0

注意:我确保用户名和密码正确。

0 个答案:

没有答案