使用Java配置+ REST身份验证的Spring Security方法级安全性?

时间:2014-11-25 09:39:15

标签: java spring rest spring-mvc spring-security

我正在尝试向我的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";
    }
}

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 {
}

我怎样才能让它发挥作用?

还有一个很好的教程可以使用基于REST配置的令牌(保存会话密钥和其他自定义值的令牌)使用Java配置的JPA(或JDBC?)保存在数据库中吗?

2 个答案:

答案 0 :(得分:2)

删除formLogin()。您需要保持REST应该是无状态的心态。以这种方式使用表单登录,不仅仅是REST。

你可以使用像这样的Spring安全链创建一个精美的蒙版过滤器(随机添加的东西来创建更完整的.Spring Security通过过滤器工作,这意味着你需要在它开始之前创建一个实际的过滤器。特别是你需要在将请求与路径匹配之前对其进行授权。

    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/

另外,请确保您在这里查看福勒关于REST的着作 http://martinfowler.com/articles/richardsonMaturityModel.html

答案 1 :(得分:0)

我忘了把我的WebApplicationInitialisation放在这个问题上。

我的错误是我将SecurityConfig放在getRootConfigClasses()而不是getServletConfigClasses()中。 现在WebApplicationInitialisation看起来像这样,它运作得很好!

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);
    }
}