Java 带嵌套帐户的Spring安全性

Java 带嵌套帐户的Spring安全性,java,spring,spring-security,Java,Spring,Spring Security,我在Spring Security中授权嵌套帐户时遇到困难。我是新来的春天安全。我花了大约一周的时间来达成一个有效的解决方案,但这是一个丑陋的解决方案,我很想重构它 我正在使用Spring4.2.4和SpringSecurity 4.0.3 我的用户帐户如下所示: 办公室用户A 办公室用户B 现场用户C -->字段子用户a -->字段子用户b 现场用户D -->字段子用户c 因此,office用户只有一个帐户,但field用户始终至少有一个子帐户,可能有两个或多个子帐户。每个子帐户可以有不同的权

我在Spring Security中授权嵌套帐户时遇到困难。我是新来的春天安全。我花了大约一周的时间来达成一个有效的解决方案,但这是一个丑陋的解决方案,我很想重构它

我正在使用Spring4.2.4和SpringSecurity 4.0.3

我的用户帐户如下所示:

办公室用户A

办公室用户B

现场用户C

-->字段子用户a

-->字段子用户b

现场用户D

-->字段子用户c

因此,office用户只有一个帐户,但field用户始终至少有一个子帐户,可能有两个或多个子帐户。每个子帐户可以有不同的权限。就像一个子帐户只能查看一样,另一个子帐户可以查看并创建

用户将使用帐户(A、B、C或D)登录。如果A或B登录,则没有问题。然而,如果用户C登录,他们需要选择(a或b),我们需要他们选择的信息。如果用户D登录,我们需要用户(c)的信息。我正在使用Spring安全性,正在努力获取上述用户a/b/c的信息。我找到了一个解决方案,但并不理想,我想知道一个更合适的方法

我的解决方案:

在UserDetails的@AuthenticationPrincipal实现中,添加以下代码:

private Collection<GrantedAuthority> authorities;
private String uniqueId1;
private String uniqueId2;
然后,在我获取登录用户信息的方法中,接受所选用户的字符串并执行以下操作:

public @ResponseBody FullUserDetails getLoggedInUserInfo(
            @AuthenticationPrincipal MyImplementationOfUserDetails user,
            String selectedUsername)

MyImplementationOfUserDetails user2 = getUserInfo(selectedUsername);

user.setAuthorities(user2.getAuthorities());
user.setUniqueId1(user2.getUniqueId1());
user.setUniqueId2(user2.getUniqueId2());
通过这种方式,我可以“更改”权限和唯一id属性,否则这些属性将是不可更改的,因为它们在父类中是私有的,通常只能通过构造函数访问我尝试在UserDetails实现中创建一个新的构造函数,但是当我创建一个新的@AuthenticationPrincipal时,它不会覆盖会话中的构造函数。我认为新的构造函数将是最合适的方法。如何使用新的UserDetails对象覆盖会话中的@AuthenticationPrincipal?还是有一个更好的方法,我没有想到?我只想要子用户的新权限和唯一ID信息,该子用户被选择放入@AuthenticationPrincipal。下次我获取@AuthenticationPrincipal时,它将拥有该信息

不获取新信息并将其放入@AuthenticationPrincipal的后果是网页行为将是错误的。主要是因为所选用户的权限级别不正确

我试着打电话:

SecurityContextHolder.getContext().setAuthentication(newAuthenticationObjectHere);
但是调用setAuthentication()后,我没有看到更改


我能够看到这些更改的唯一方法是直接调用从@AuthenticationPrinciple检索到的MyImplementationOfUserDetails对象中的setter。

抱歉,非常困惑,但主要思想几乎可以理解

我认为你有一个循环的想法来计算帐户之间的所有复杂关系,然后给最终帐户所需的权限,并提供对某些资源的访问

如果要在不操纵帐户关系的情况下更改提供资源访问权限的逻辑,该怎么办?还有一个非常重要的环节——使用远程/分布式授权服务器,比如SpringOAuth2One?使用它,您可以拥有任何帐户和作用域的权限(!)。根据组织条件,帐户可以具有不同的作用域。您的最终资源(通常是控制器方法)具有按范围进行的预身份验证。根据这一思想,您可以根据帐户的具体类型分离提供访问的逻辑,用帐户实现数据库中的所有逻辑

对你的项目来说,这可能是错误的想法,对我来说,它是有效的——我根据客户的条件更改范围,但不在运行时处理他们的数据和关系

public void setUniqueId2(String uniqueId2) {
    this.uniqueId2 = uniqueId2;
}

public String getUniqueId2() {
    if (this.uniqueId2!= null) {
        return this.uniqueId2; //CHILD
    }
    return super.getUniqueId2(); // (SUPER)
}
public @ResponseBody FullUserDetails getLoggedInUserInfo(
            @AuthenticationPrincipal MyImplementationOfUserDetails user,
            String selectedUsername)

MyImplementationOfUserDetails user2 = getUserInfo(selectedUsername);

user.setAuthorities(user2.getAuthorities());
user.setUniqueId1(user2.getUniqueId1());
user.setUniqueId2(user2.getUniqueId2());
SecurityContextHolder.getContext().setAuthentication(newAuthenticationObjectHere);