我猜你想拥有两组资源。其中一个对公众开放,可在/public context 中获取,另一个受保护,可在/protected 获取。
首先,您应该在您的Web Configuration 中创建一些Resource Handlers:
@EnableWebMvc
@Configuration
public class WebConfig extends WebMvcConfigurerAdapter {
// other stuffs
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/public/**").addResourceLocations("classpath:/public/");
registry.addResourceHandler("/protected/**").addResourceLocations("classpath:/resources/");
}
}
这样/public 目录中的所有静态内容将在/public/** 端点提供,/protected/** 端点将在/resources 目录中提供文件。
那么你应该配置 Spring Security 以保护 /protected/** 端点:
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
// other stuffs
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/public/**").permitAll()
.antMatchers("/protected/**").authenticated()
.anyRequest().authenticated();
}
}
更新对于 REST 端点,您可以使用相同的匹配器或使用Method Level Security 进行更精细的粒度控制。为了启用方法级别的安全性,请将@EnableGlobalMethodSecurity(prePostEnabled = true) 添加到您的SecurityConfig。然后您可以在处理方法上使用PrePost 注释,如下所示:
@RestController
@RequestMapping("/greet")
public class GreetingService {
// it's a public rest endpoint
@PreAuthorize("permitAll()")
@RequestMapping("/public")
public void doGreetToPublicUsers() {...}
// it's a protected rest endpoint
@PreAuthorize("isAuthenticated()")
@RequestMapping("/protected")
public void doGreetToProtectedUsers() {...}
// it's a role protected rest endpoint
@PreAuthorize("hasRole('ROLE_ADMIN')")
@RequestMapping("/admin")
public void justForAdmin() {...}
}