我是Spring安全的新手,我学会了用JWT构建restful API。 我搜索了互联网如何在某个终点验证用户,但问题是所有终点都要求身份验证,包括登录(我不想要),即使我允许这样做。
@EnableGlobalMethodSecurity(prePostEnabled = true)
@EnableWebSecurity
@Configuration
public class SecurityUtility 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;
}
private static final String[] PUBLIC_MATCHERS = {
"/login",
"/logout",
"/forgot-password"
};
@Override
public void configure(WebSecurity web) throws Exception {
web.ignoring().antMatchers(HttpMethod.POST,
"/login",
"/forgot-password"
);
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable()
.authorizeRequests().antMatchers(PUBLIC_MATCHERS).permitAll().anyRequest().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("/**");
}
@Override
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response)
throws AuthenticationException, IOException, ServletException {
String header = request.getHeader("Authorization");
if(header== null || !header.startsWith("Token "))
throw new RuntimeException("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);
}
}
但是当我在路径上添加类似前缀(如下所示)时,它可以正常工作。
public JwtAuthenticationTokenFilter() {
super("/api/**");
}
所以我可以在没有在我的终点之前添加任何内容的情况下执行此操作。这样我就可以允许一些终点并对其余的进行验证。
答案 0 :(得分:0)
在SecurityUtility类中,您可以覆盖WebSecurityConfigurerAdapter类的configure(WebSecurity web)
方法。
@Override
public void configure(WebSecurity web) throws Exception {
// JwtAuthenticationTokenFilter will ignore the below paths
web.ignoring().antMatchers(
HttpMethod.POST,
"/api/auth/**"
);
web.ignoring().antMatchers(
HttpMethod.GET,
"/",
"/actuator/**",
"/beer/**",
"/comment/**",
"/signIn",
"/asset-manifest.json",
"/favicon.ico",
"/index.html",
"/service-worker.js",
"/static/**",
"/webjars/**",
"/*.html",
"/favicon.ico",
"/**/*.html",
"/**/*.css",
"/**/*.js"
);
}
}
的示例答案 1 :(得分:-1)
您可以尝试以下代码:
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable().exceptionHandling()
.authenticationEntryPoint(entryPoint).and()
.anonymous().and()
.servletApi().and()
.headers().cacheControl().and()
.and()
.authorizeRequests()
.antMatchers(PUBLIC_MATCHERS).permitAll()
.antMatchers("/images/**").permitAll()
.antMatchers(HttpMethod.OPTIONS, "/**").permitAll()
.anyRequest().authenticated().and()
.addFilterBefore(authenticationTokenFilter(), UsernamePasswordAuthenticationFilter.class);
}