【问题标题】:Ensure that users can only access their data in a REST API request确保用户只能在 REST API 请求中访问他们的数据
【发布时间】:2017-11-06 13:35:57
【问题描述】:

我现在正在 Spring 的 Jersey 使用 REST API。稍后应使用 Android/iOS 访问。 例如,如果我在 Jersey 资源中有类似 @Path("/user/{userID}/settings") 的用户设置。我如何确保每个用户只能访问他/她的设置?我已经阅读了很多关于 spring-security-oauth2 的内容。但据我了解,您只能验证用户是否真的是用户,但如果他/她可以访问其他用户设置,则不会有所作为?!

【问题讨论】:

  • 在每次请求私有数据之前验证用户是否经过身份验证。
  • 您可能需要额外的安全层来执行您需要的操作。 OAuth 允许您对用户进行身份验证,甚至分配角色,但您需要保护每个 URL 路径,例如。 /user/ABC/settings/user/DEF/settings 分别用于角色/权限。根据 J-Alex 在下面的回答,安全性可以在 Jersey 框架(例如您的负载均衡器)之上的层中提供,也可以在其内部提供。第二个选项更容易。

标签: java android spring rest oauth-2.0


【解决方案1】:

您需要的是授权。

授权可以区分每个用户的访问级别。 其实是个大话题。您可以使用角色、权限、ACL 来保护服务。

解决您的任务的最简单方法是使用路径/user/settings 并找到您自己的身份验证,例如:

public Settings find() {
    UserDetails customUserDetails = (CustomUserDetails) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
    return setingsService.findByUser(customUserDetails.getUsername());
}

创建您的 CustomUserDetails:

public class CustomUserDetails implements UserDetails {

    private User user;

    private Collection<? extends GrantedAuthority> authorities;

    public CustomUserDetails(User user) {
        this.user = user;
    }

    public User getUser() {
        return user;
    }

    @Override
    public Collection<? extends GrantedAuthority> getAuthorities() {
        List<GrantedAuthority> authorities = new ArrayList<>();

        for (Authority authority : user.getAuthorities()) {
            authorities.add(new SimpleGrantedAuthority(authority.getName()));
        }

        return authorities;
    }

    @Override
    public String getPassword() {
        return user.getPassword();
    }

    @Override
    public String getUsername() {
        return user.getUsername();
    }

    // implement other methods  

}

还有 CustomUserDetailsS​​ervice:

@Service
public class CustomUserDetailsService implements UserDetailsService {

    @Autowired
    private UserService userService;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        User user = userService.findByUsername(username);
            // check if exist
        }

        return new CustomUserDetails(user);
    }
}

【讨论】:

  • 没有理由改变路径,而且对SecurityContextHolder.getContext().getAuthentication().getPrincipal() 的调用似乎在某种程度上打破了 REST 原则......服务器端不需要保存上下文。同样的原则可以在没有设置安全上下文的情况下应用,只查看请求。
猜你喜欢
  • 2022-01-16
  • 2014-11-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-03-23
  • 2015-07-26
  • 2020-11-04
  • 1970-01-01
相关资源
最近更新 更多