使用JWT的Spring Boot应用程序的HttpServletRequest中缺少授权令牌

时间:2019-05-29 21:10:03

标签: spring-boot spring-security jwt

我在Spring Boot应用程序的HttpServletRequest对象中访问Authorization令牌存在问题。我已经实现了JWT和spring安全性。当API请求来自邮递员(其他客户)时,我可以获取授权令牌。但是,如果请求来自浏览器,它将不会在那里。我认为这是由于浏览器的安全功能。但是,即使我是如何实现的?

 @EnableGlobalMethodSecurity(prePostEnabled = true)
    @EnableWebSecurity
    @Configuration
    public class JwtSecurityConfig extends WebSecurityConfigurerAdapter {


        @Autowired
        private JwtAuthenticationProvider authenticationProvider;
        @Autowired
        private JwtAuthenticationEntryPoint entryPoint;

        @Bean
        public AuthenticationManager authenticationManager() {
            return new ProviderManager(Collections.singletonList(authenticationProvider));
        }

        @Bean
        public JwtAuthenticationTokenFilter authenticationTokenFilter() {
            JwtAuthenticationTokenFilter filter = new JwtAuthenticationTokenFilter();
            filter.setAuthenticationManager(authenticationManager());
            filter.setAuthenticationSuccessHandler(new JwtSuccessHandler());
            return filter;
        }


        @Override
        protected void configure(HttpSecurity http) throws Exception {

            http.csrf().disable()
                    .authorizeRequests().antMatchers("**/rest/**").authenticated()
                    .and()
                    .exceptionHandling().authenticationEntryPoint(entryPoint)
                    .and()
                    .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);

            http.addFilterBefore(authenticationTokenFilter(), UsernamePasswordAuthenticationFilter.class);
http.headers().cacheControl();

        }
    }


public class JwtAuthenticationTokenFilter extends AbstractAuthenticationProcessingFilter {

    public JwtAuthenticationTokenFilter() {
        super("/rest/**");
    }

    @Override
    public Authentication attemptAuthentication(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws AuthenticationException, IOException, ServletException {

        String header = httpServletRequest.getHeader("Authorization");


        if (header == null || !header.startsWith("Token ")) {
            throw new RuntimeException("JWT Token is missing");
        }

        String authenticationToken = header.substring(6);

        JwtAuthenticationToken token = new JwtAuthenticationToken(authenticationToken);
        return getAuthenticationManager().authenticate(token);
    }


    @Override
    protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain, Authentication authResult) throws IOException, ServletException {
        super.successfulAuthentication(request, response, chain, authResult);
        chain.doFilter(request, response);
    }
}

@Component
public class JwtAuthenticationProvider extends AbstractUserDetailsAuthenticationProvider {

    @Autowired
    private JwtValidator validator;

    @Override
    protected void additionalAuthenticationChecks(UserDetails userDetails, UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken) throws AuthenticationException {

    }

    @Override
    protected UserDetails retrieveUser(String username, UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken) throws AuthenticationException {

        JwtAuthenticationToken jwtAuthenticationToken = (JwtAuthenticationToken) usernamePasswordAuthenticationToken;
        String token = jwtAuthenticationToken.getToken();

        JwtUser jwtUser = validator.validate(token);

        if (jwtUser == null) {
            throw new RuntimeException("JWT Token is incorrect");
        }

        List<GrantedAuthority> grantedAuthorities = AuthorityUtils
                .commaSeparatedStringToAuthorityList(jwtUser.getRole());
        return new JwtUserDetails(jwtUser.getUserName(), jwtUser.getId(),
                token,
                grantedAuthorities);
    }

    @Override
    public boolean supports(Class<?> aClass) {
        return (JwtAuthenticationToken.class.isAssignableFrom(aClass));
    }
}


@Component
public class JwtAuthenticationEntryPoint implements AuthenticationEntryPoint {
    @Override
    public void commence(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AuthenticationException e) throws IOException, ServletException {

        httpServletResponse.sendError(HttpServletResponse.SC_UNAUTHORIZED, "UNAUTHORIZED");
    }
}

public class JwtSuccessHandler implements AuthenticationSuccessHandler{
    @Override
    public void onAuthenticationSuccess(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Authentication authentication) throws IOException, ServletException {
        System.out.println("Successfully Authentication");
    }
}

我们可以看到我在JwtAuthenticationTokenFilter类的名为key的标头中获取了Authorization令牌。

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">

  <title>AJAX practice</title>
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
  <script>
   function apicall(){

   $.ajax({
    url: 'http://localhost:9000/rest/',
    crossDomain: true,
    headers: {
        'Authorization': `Bearer Sample-Token`,
    },
    method: 'POST',
    data: {
        userId:1,
        astSearchId:0,
        searchType:2
    },
    success: function(data){
      console.log('succes: '+data);
    }
  });

   }

  </script>
</head>
<body>
    <div class="title">
      <h1>Hi</h1>
    </div>
    <button onclick="apicall()">Click</button>
  <br>
  <br>
  <label id="data">......</label>
    </p>
</body>
</html>

0 个答案:

没有答案