有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

带嵌套帐户的java Spring安全性

我在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 void setAuthorities(Collection<GrantedAuthority> authorities) {
    this.authorities = authorities;
}

public Collection<GrantedAuthority> getAuthorities() {
    if (this.authorities != null) {
        return this.authorities; //CHILD
    }
    return super.getAuthorities(); // (SUPER)
}
public void setUniqueId1(String uniqueId1) {
    this.uniqueId1 = uniqueId1;
}

public String getUniqueId1() {
    if (this.uniqueId1!= null) {
        return this.uniqueId1; //CHILD
    }
    return super.getUniqueId1(); // (SUPER)
}
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());

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

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

我试着打电话:

SecurityContextHolder.getContext().setAuthentication(newAuthenticationObjectHere);

但是调用setAuthentication()后,我没有看到更改

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


共 (1) 个答案

  1. # 1 楼答案

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

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

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

    也许这对你的项目来说是个错误的想法,对我来说是可行的——我会根据客户的情况更改范围,但不会在运行时处理他们的数据和关系