我在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>