I guess you want to have two sets of resources. One of them is open for public access and available at, say, /public
context and the other is protected and available at /protected
.
First, you should create some Resource Handlers
in your Web Configuration
:
@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/");
}
}
This way all the static contents in /public
directory will be served at /public/**
endpoint and /protected/**
endpoint will serve files in the /resources
directory.
Then you should configure Spring Security in order to protect /protected/**
endpoint:
@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();
}
}
Update For REST endpoints you can either use same the matchers or have finer grain control with Method Level Security
. In order to enable method level security, add @EnableGlobalMethodSecurity(prePostEnabled = true)
to your SecurityConfig
. Then you can use PrePost
annotations on hanlder methods, like following:
@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() {...}
}