【问题标题】:Spring Security allow each user to see their own profile but none elseSpring Security 允许每个用户查看他们自己的个人资料,但没有其他人
【发布时间】:2018-10-11 10:03:50
【问题描述】:

在带有 Spring Security 的 Spring MVC 中,是否有可能实现这一点?

@Override WebSecurityConfigurerAdapter.configure(HttpSecurity)

@Override
protected void configure(HttpSecurity http) throws Exception
{
    http
            .authorizeRequests()
            .mvcMatchers("/users/{authentication.principal.username}").hasAnyRole(ADMIN, MANAGER)
            .antMatchers("/users/**").hasRole(ADMIN)
            .anyRequest().authorized()
    ...
}

/users/** 是一个禁区,只能由管理员访问。但是管理员应该仍然能够看到他们自己的个人资料 (/users/user_with_manager_role),而且只能看到他们自己的个人资料,而不是任何其他用户的个人资料(无论他们的角色如何)。


解决方案

我在 Andrew 的回答中找到了解决方案。我的代码现在看起来像这样:

WebSecurityConfigurerAdapter

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true) // added this annotation
public class SecurityConfig extends WebSecurityConfigurerAdapter

@Override WebSecurityConfigurerAdapter.configure(HttpSecurity)

@Override
protected void configure(HttpSecurity http) throws Exception
{
    http
            .authorizeRequests()
            // removed /users handling
            .anyRequest().authorized()
    ...
}

用户控制器

@Controller
@RequestMapping("/users")
public class UsersController
{
    @GetMapping("{username}")
    @PreAuthorize("authentication.principal.username == #username) || hasRole('ADMIN')")
    public String usersGet(@PathVariable("username") String username)
    {
        // do something with username, for example get a User object from a JPA repository
        return "user";
    }
}

【问题讨论】:

  • 不要将解决方案编辑到您的问题中。只需为您的问题添加一个新答案。因此,我回滚了您的编辑。您可以从历史记录中复制您的答案以添加新答案。

标签: java spring-mvc spring-security authorization


【解决方案1】:

恐怕这是不可能的:在设置此配置时,它没有关于 {authentication.principal.username} 的信息,这将在将来的某个时候得到解决。

但是 Spring 为您提供了一堆内置的 method security expressions,您可以使用它们来注释您的方法。

@PreAuthorize("hasRole('ADMIN')") 这样的简单表达式开始,您可能会得到一个自定义表达式:

@XMapping(path = "/users/{username}")
@PreAuthorize("@yourSecurityService.isMyPage(authentication.principal, #username)")
public void yourControllerMethod(@PathVariable String username);

@yourSecurityService.isMyPage(authentication.principal, #username) 指的是你的@Service 方法public boolean isMyPage(Principal, String)

【讨论】:

    【解决方案2】:

    这样的事情怎么样:

    @Override
    protected void configure(HttpSecurity http) throws Exception
    {
        http
                .authorizeRequests()
                .antMatchers(HttpMethod.GET, "/myself").hasAnyRole(ADMIN, MANAGER)
                .antMatchers("/users/**").hasRole(ADMIN)
                .anyRequest().hasAnyRole(ADMIN, MANAGER)
        ...
    }
    
    @RequestMapping(value = "/myself", method = RequestMethod.GET)
    public Profile getMyself() {
        // return the profile of the loged in user
    }
    

    有了这个经理,管理员可以获取他们自己的个人资料,管理员也可以通过/users/{username}请求其他个人资料。

    【讨论】:

      猜你喜欢
      • 2017-11-10
      • 1970-01-01
      • 2023-04-10
      • 1970-01-01
      • 2011-05-20
      • 2015-10-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多