我正在尝试向我的 RestController 添加身份验证,但我找不到任何好的文档或任何 Java 配置示例。
我试过这个,但它不起作用(我可以在没有登录的情况下访问所有请求)
我的控制器带有注释@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";
}
}
安全配置
@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();
}
}
}
安全性 Web 应用程序初始值设定项
public class SecurityWebApplicationInitializer extends AbstractSecurityWebApplicationInitializer {
}
我怎样才能让它工作?
并且有任何很好的教程可以使基于REST令牌(保存会话密钥和其他自定义值的令牌)身份验证保存在数据库中,并使用Java配置使用JPA(或JDBC?
删除 formLogin()。你需要保持REST应该是无状态的心态。以这种方式使用表单登录并不是纯粹的 REST。
你可以像这样用Spring安全链创建一个精细的屏蔽过滤器(随机添加的东西来创建更完整的。Spring 安全性通过过滤器工作,这意味着您需要在它启动之前创建一个实际的过滤器。具体而言,您需要先授权请求,然后再将其与路径匹配。
http.authorizeRequests()
.antMatchers("/login").permitAll()
.antMatchers("/say/user/").hasRole("USER")
.antMatchers("/say/admin").hasRole("ADMIN")
.anyRequest().authenticated();
上面的代码应该是不言自明的。如果没有,我将尝试详细说明。
至于基于令牌的登录,这是一个好主意,但你不应该自己动手。Spring 有很好的 Oauth 支持,开始使用它保护你的 REST API 非常棒。
本教程非常详细地解释了它,并且应该可以帮助您进一步构建更好的API。http://spring.io/guides/tutorials/bookmarks/
另外,请确保你在这里看看Fowler关于REST的著作。http://martinfowler.com/articles/richardsonMaturityModel.html
我忘了把我的WebApplicationInitialisation放在问题中。
我的错误是我把SecurityConfig放在getRootConfigClasses()而不是getServletConfigClasses()中。现在Web应用程序初始化看起来像这样,它工作得很好!
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);
}
}