Java 确保特定用户只能看到自己的用户详细信息-使用Spring

Java 确保特定用户只能看到自己的用户详细信息-使用Spring,java,spring,spring-boot,spring-mvc,spring-security,Java,Spring,Spring Boot,Spring Mvc,Spring Security,目前正在一个小项目上使用Spring/Spring security,并且难以实现此功能。理想情况下,我只希望user1查看user1的详细信息,而不是2、3或4的详细信息 我已经用角色实现了Spring安全性,并且了解我可以检索UserDetails对象或原则,我不确定确切的情况,但我知道我可以使用其中一种方法检索当前登录用户的详细信息,这似乎是许多方法中的一种 这是我目前在进入管理员/主页时用作概念证明的内容: Authentication auth = SecurityContextHol

目前正在一个小项目上使用Spring/Spring security,并且难以实现此功能。理想情况下,我只希望user1查看user1的详细信息,而不是2、3或4的详细信息

我已经用角色实现了Spring安全性,并且了解我可以检索UserDetails对象或原则,我不确定确切的情况,但我知道我可以使用其中一种方法检索当前登录用户的详细信息,这似乎是许多方法中的一种

这是我目前在进入管理员/主页时用作概念证明的内容:

Authentication auth = SecurityContextHolder.getContext().getAuthentication();
    Gamer gamer = gamerService.findGamerByEmail(auth.getName());

    System.out.println("Auth: " + auth.getName());
    System.out.println("Gamer: " + gamer.getName() + gamer.getId() + gamer.getEmail());
安全配置会考虑当前用户是否可以访问分配给它的角色

我相信我应该能够访问
/mysite/viewUserDetails
的url,让该页面显示当前用户的信息,但我找不到任何这样的例子,我找到了很多例子,证明登录用户可以查看页面,但没有一个指定检查以确保user1只能查看user1的详细信息

在以前的页面上,我这样做是为了显示特定用户的信息,但我知道这是一种不好的做法-

<a th:href="@{/gamer/{gamerid}/games/excited (gamerid=${gamer.id}) }">
所以我的问题变成了,我希望你能指出正确的方向,我如何实现一个解决方案,用户只能查看他/她的详细信息,这应该如何通过表单和连接控制器来表示,因为在url中传递ID有点难看(我可以使用guid,但是…)


非常感谢。

请查看
@PreAuthorize
注释。可以用它注释给定的端点,并在bean中创建自定义逻辑。然后,您可以使用自定义方法允许或不允许端点继续:

@Controller
public class HomeController {

    @Autowired
    private AuthenticationService authenticationService;

    @RequestMapping("/gamer/{gamerid}/games/excited")
    @PreAuthorize("@authenticationService.hasAccess(#gamerid)")
    public String getExcited(@PathVariable final Long gamerid, Model model){

        addGamerListAttributes(model, gamerid, "EXC");
        return "games";
    }
}
服务类别:

@Service
public class AuthenticationService {
    public boolean hasAccess(String tgamerid) {
        //implement logic here
        return true;
    }
}

AuthenticationService
中的方法
hasAccess
应返回布尔值<代码>@PreAuthorize将在调用控制器处理程序方法之前启动。上面的控制器只是一个例子。您可以将
@PreAuthorize
注释中SPeL表达式中的
Authentication
对象传递给服务方法,或者从服务类中的安全上下文获取它,以实现符合您需要的逻辑。您可以在中找到更多信息。

这实际上是一个非常简单的选择。要么您有一个入口点,如:

@RequestMapping("/gamer/{gamerid}/games/excited")
您可以手动检查会话中的用户是否可以访问请求的资源,或者您是否有

@RequestMapping("/my-games")
从安全上下文中自动读取用户id的


不仅仅是一种安全选择,我会根据代码重用和未来的使用情况选择一种(例如,同一页面/页面集可以被多个用户看到)。

感谢Raffaele,很抱歉延迟回复,我们离开了几天。我更喜欢第二个选项,因为我不想在任何地方传递用户ID,特别是在url中。至于代码重用,我正处于开发的早期阶段,未来的设计还没有完全规划出来——这是一个爱好/学习项目,比任何其他项目都重要。使用第二个,我看到了如何通过提取显示我需要的内容,我是否正确地认为从securitycontext中提取id意味着其他用户将无法在任何地方“注入”id并查看其他人的数据?谢谢Michalk,很抱歉延迟回复!我喜欢预授权可以提供什么的想法,看起来非常优雅。我确实更喜欢这样的选项,即不传入INI,而是从securitycontext中提取。我认为,除了从SC中提取想法之外,还有“hasAccess”可能有些多余?在我的解决方案中,您必须从SC中获取gamerId,并将其与从pathVariable中获取gamerId进行比较,例如,检查它们是否相同或实现任何其他逻辑。不在路径中传递gamerId并从SC获取基于gamerId的玩家游戏的选项只是另一个选项,它取决于您将选择什么。好的,但是如果我从路径中移除gamerId,那么我认为这就不需要进行检查了?如果它是/getmygames,然后在我从SC提取的控制器中,根据您的经验,它可以工作吗?如果您从路径中删除gamerId,我还需要预授权吗?在这种情况下,预授权将是无用的。
@RequestMapping("/my-games")