Reputation: 1550
I'm trying to add an authentification to my RestController, but i can't find any good documentation or any sample with Java Configuration.
I tried this but it doesn't work (i can access to all request without login)
My controller is annotated with @PreAuthorize
@RestController
@RequestMapping("/api/hello")
public class HelloController {
@RequestMapping(value = "/say", method = RequestMethod.GET)
public String sayHello() {
return "hello";
}
@PreAuthorize("hasRole('ROLE_USER')")
@RequestMapping(value = "/say/user", method = RequestMethod.GET)
public String sayHelloWithUserProtection(){
return "Hello USER";
}
@PreAuthorize("hasRole('ROLE_ADMIN')")
@RequestMapping(value = "/say/admin", method = RequestMethod.GET)
public String sayHelloWithAdminrProtection(){
return "Hello ADMIN";
}
}
SecurityConfig
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
@ComponentScan(basePackages = {"com.test.server.security"})
public class SecurityConfig {
@Autowired
public void configureAuthentification(AuthenticationManagerBuilder auth) throws Exception {
auth
.inMemoryAuthentication()
.withUser("user").password("password").roles("USER").and()
.withUser("admin").password("admin").roles("USER","ADMIN");
}
@Configuration
public static class ApiWebConfigurerAdapter extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.antMatcher("/api/**")
.formLogin();
}
}
}
SecurityWebApplicationInitializer
public class SecurityWebApplicationInitializer extends AbstractSecurityWebApplicationInitializer {
}
How can i make it work?
And there is any good tutorial to make a REST token based (token which save session key and others custom values) authentification saved in database with JPA (or JDBC ?) with Java configuration ?
Upvotes: 1
Views: 1066
Reputation: 1550
I forgot to put my WebApplicationInitialisation in the question.
My error was i put SecurityConfig in getRootConfigClasses() instead of getServletConfigClasses(). Now WebApplicationInitialisation looks like this and it work great !
public class WebApplicationInitialisation extends AbstractAnnotationConfigDispatcherServletInitializer {
@Override
protected Class<?>[] getRootConfigClasses() {
return new Class[]{RootConfig.class};
}
@Override
protected Class<?>[] getServletConfigClasses() {
return new Class[]{WebMvcConfig.class, SecurityConfig.class};
}
@Override
protected String[] getServletMappings() {
return new String[]{"/"};
}
@Override
public void onStartup(ServletContext servletContext) throws ServletException {
super.onStartup(servletContext);
}
}
Upvotes: 0
Reputation: 265
Drop the formLogin(). You need to maintain the mindset that REST is supposed to be stateless. Logging in with a form this way, is not purely REST.
You can create a fine masked filter with Spring security chains like this (randomly just added stuff to create a more complete. Spring Security works by filters, which means that you need to create an actual filter before it kicks in. Specifically you need to authorize requests before matching them to paths.
http.authorizeRequests()
.antMatchers("/login").permitAll()
.antMatchers("/say/user/").hasRole("USER")
.antMatchers("/say/admin").hasRole("ADMIN")
.anyRequest().authenticated();
The code above should be self explaining. If not, I will try to elaborate on it.
As for token based login, this is a good idea, but you should not roll your own. Spring has great Oauth support and getting started securing your REST API with it is awesome.
This tutorial explains it in great detail and should help you further in building better API's as well. http://spring.io/guides/tutorials/bookmarks/
Also make sure you have a look at Fowler's writings on REST here http://martinfowler.com/articles/richardsonMaturityModel.html
Upvotes: 2