Spring security 只允许访问具有特定用户名的用户

Paw*_*ski 4 java spring spring-mvc spring-security spring-boot

我正在开发一个 Spring Boot 应用程序并为用户编写一个 API 以便能够阅读消息。URL之一是:

/users/USER1/messages
Run Code Online (Sandbox Code Playgroud)

现在,我显然希望只有经过身份验证的用户才能访问此 get 请求的内容。但是所有经过身份验证的用户是不够的。我还希望只有拥有用户名的用户 - USER1 才能在这里查看真实内容,其余的应该收到 403 状态。我想出了如何在没有 spring 安全配置的情况下执行此操作(在我的服务中,我正在检查登录的用户名并将其与 URL 中的参数进行比较,仅当它们相等时才继续),但我认为应该有一种更简单的方法只使用 SecurityConfiguration?我当前的配置如下所示:

@Configuration
@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
            .antMatchers(HttpMethod.GET, "/users/**").authenticated()
            .antMatchers("/h2-console/*").permitAll()
                .anyRequest().authenticated()
            .and()
                .formLogin();

        http.csrf().disable();
        http.headers().frameOptions().disable();
    }

    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        auth.inMemoryAuthentication()
                .withUser("superman").password("superman").roles("USER")
                .and()
                .withUser("admin").password("admin").roles("ADMIN");
    }
}
Run Code Online (Sandbox Code Playgroud)

编辑:以下回答建议方法安全表达式我已经使用了它,但它似乎仍然不起作用(如果我被认证为 USER2,我仍然可以读取 USER1 的消息)。这是我添加了 PreAuthorize 注释的控制器

@RequestMapping(method = RequestMethod.GET, value = "/messages", produces = {"application/json"})
@ResponseBody
@PreAuthorize("#userHandle == authentication.name")
public List<Message> getMessages(@PathVariable("userHandle") String userHandle,
                        @RequestParam(value="search", defaultValue="") String search) {
    //todo: change to return DTO not model
    return messageFacade.getMessages(userHandle, search);
}
Run Code Online (Sandbox Code Playgroud)

EDIT2:在接受的答案@EnableGlobalMethodSecurity(prePostEnabled=true) 中的评论中需要包含在安全配置中。一旦包括在内,一切正常。

Ass*_*lov 8

我认为您需要 Spring Method Security。文档中的例子几乎就是你的情况:

import org.springframework.data.repository.query.Param;

...

@PreAuthorize("#n == authentication.name")
Contact findContactByName(@Param("n") String name);
Run Code Online (Sandbox Code Playgroud)

PS:别忘了@EnableGlobalMethodSecurity在此处查看教程

  • 你有`@EnableGlobalMethodSecurity` 吗? (2认同)
  • 必须首先启用方法安全注释。见 https://spring.io/blog/2013/07/04/spring-security-java-config-preview-method-security/ (2认同)