Spring REST Api——访问存储库中的用户详细信息

Posted

技术标签:

【中文标题】Spring REST Api——访问存储库中的用户详细信息【英文标题】:Spring REST Api -- access User details in repository 【发布时间】:2017-12-29 23:20:49 【问题描述】:

RESPApi项目的设置是:

SpringBoot Spring 的 OAuth2

在项目中,我们有很多客户端,因此 SQL 查询几乎总是在 where 子句中包含 "... and clientId = ?"

我们将clientId 与其他用户详细信息一起存储在SecurityContext 中(我们扩展了Spring 的User 类)。

问题是:如何获取@Repository中的User对象?

我们能想到的可能解决方案:

    在每个存储库实现中添加

SecurityContextHolder.getContext().getAuthentication()

将结果转换为我们的自定义 UserDetails 实现并使用它。

缺点:不知何故,我觉得有更好的解决方案。

    @AuthenticationPrincipal注解的参数添加到控制器,然后将参数传递给服务层,然后再传递到存储库层。

缺点:通过 2 层参数仅获得clientId 似乎不合理。

我想到了@Repository 类中的@Autowired 参数MyUser user。第一次尝试是创建@Configuration 注释类,其中将有一个方法

    @Bean
public MyUser getUser() 
    SecurityContext context = SecurityContextHolder.getContext();
    if (context != null) 
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        if (authentication != null) 
            return (MyUser) authentication.getPrincipal();
        
    
    return null;

但是 bean 是空的,我不能使用它。

目前我们已经找到了解决方案 nr 1,但我觉得一定有更好的方法。

任何想法如何解决这个问题?

【问题讨论】:

【参考方案1】:

如果您正在使用Spring Data(或有时间改用它),您可以在查询中直接使用SecurityEvaluationContextExtensionprincipal: https://***.com/a/29692158/1777072

如果没有,你可以隐藏静态访问,如果它冒犯了(或者如果你想在未来对它进行更多控制):

@Component
public class AuthenticationHelper 
    public Authentication getAuthentication() 
        return SecurityContextHolder.getContext().getAuthentication();
    

然后将该类注入到您的存储库中。

或您的服务。这可能比存储库更合适。

我喜欢让存储库保持沉默(最终使用 Spring Data 来避免完全编写它们)。

而且我喜欢将服务视为与 Web 层分离,在单独的盒子上运行(即使它们不是)。在这种情况下,您永远不会通过 HTTP 将身份验证详细信息从控制器传递到服务。该服务将为自己获取身份验证详细信息,而不仅仅是信任 Web 层发送的内容。

所以我认为 Service 应该自己获取详细信息,而不是 Controller 传递它们。

【讨论】:

【参考方案2】:

您的 bean 为 null,因为默认情况下 bean 是单例的,它们是在应用程序启动时创建的,并且您可以想象,此时您不会有 SecurityContext

尝试使用请求范围声明您的 bean,以这种方式:

@Bean
@Scope(value=WebApplicationContext.SCOPE_REQUEST, proxyMode=ScopedProxyMode.TARGET_CLASS)
public MyUser getUser() 
   .....

【讨论】:

以上是关于Spring REST Api——访问存储库中的用户详细信息的主要内容,如果未能解决你的问题,请参考以下文章

Spring Boot 存储库中的 API 与 DAO

无法从同一网络中的另一台计算机访问在我的计算机中运行的 SPRING BOOT 应用程序的 REST API

PayPal REST API 为信用卡令牌返回 500 服务器错误

使用 REST Api 授权访问商家的实时交易

如何从 Spring Cloud 配置服务器存储和访问 html 文件?

在 Spring-boot 中成功登录后如何限制 POST Rest Api 以供公共访问