Spring Security允​​许每个用户看到他们自己的配置文件,但是没有其他

时间:2018-10-11 10:03:50

标签: java spring-mvc spring-security authorization

在具有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),并且只能看到自己的个人资料,而不是其他任何用户的个人资料(无论其角色如何)。


解决方案

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

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()
    ...
}

UsersController

@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";
    }
}

2 个答案:

答案 0 :(得分: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)

答案 1 :(得分:1)

这样的事情如何:

@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}请求其他个人资料。