【问题标题】:Unable to pass the extra parameter to Spring-Security with OAuth2.0无法使用 OAuth2.0 将额外参数传递给 Spring-Security
【发布时间】:2019-06-18 23:27:49
【问题描述】:

美好的一天。

我需要根据以下 URL 使用 springboot2 来实现带有 spring-security 的 OAuth2。

网址名称: https://www.devglan.com/spring-security/spring-boot-oauth2-jwt-example

我做到了。

这里我在验证用户时对上述代码有另一个不同的要求。

我需要在邮递员工具的 x-www-form-urlencoded 选项卡中传递 companyId 以及用户名和密码以及 grant_type(password)。 我必须根据用户名和 companyId 获取用户。

所以请帮我看看我需要在上面的链接代码中做些什么改变,这样我才能达到我的要求。

在这里我只收到电子邮件。我需要电子邮件和 companyId。

@Override
@Transactional
public UserDetails loadUserByUsername(String email) throws UsernameNotFoundException {

    User user = userRepository.findByEmail(email).orElseThrow(
            () -> new UsernameNotFoundException("User Not Found with -> username or email : " + email));
    return UserPrinciple.build(user);
}

Expected:

@Override
@Transactional
public UserDetails loadUserByUsername(String email) throws UsernameNotFoundException {

    User user = userRepository.findByEmailAndCompanyId(email,companyId).orElseThrow(
            () -> new UsernameNotFoundException("User Not Found with -> username or email : " + email));
    return UserPrinciple.build(user);
}

目前使用用户名和密码可以正常工作。

但在我的系统中,我将同一用户映射到不同的公司。如果发现同一用户映射到多个公司,我会收到如下错误。

{ “错误”:“未经授权”, “error_description”:“查询未返回唯一结果:2;嵌套异常为 javax.persistence.NonUniqueResultException:查询未返回唯一结果:2” }

我需要根据用户名和密码以及导致单个用户的 companyId 获取用户。

有人可以帮助解决这个问题吗?提前非常感谢。

【问题讨论】:

  • 您的存储库似乎返回 2 个结果而不是 1 个(就像例外所说的那样),所以我猜这 2 个结果无法映射到您的用户对象上。

标签: java spring-boot spring-security oauth


【解决方案1】:

如果您需要访问令牌的其他信息,您可以使用 TokenEnhancer 类来做到这一点。

CustomTokenEnhancer.java

public class CustomTokenEnhancer implements TokenEnhancer {

    @Override
    public OAuth2AccessToken enhance(OAuth2AccessToken accessToken, OAuth2Authentication authentication) {
        User user = (User) authentication.getPrincipal();
        final Map<String, Object> additionalInfo = new HashMap<>();

        additionalInfo.put("id", user.getCompanyId());
        additionalInfo.put("authorities", user.getAuthorities());

        ((DefaultOAuth2AccessToken) accessToken).setAdditionalInformation(additionalInfo);

        return accessToken;
    }

}

然后使用此类的实例来 void configure(AuthorizationServerEndpointsConfigurer endpoints) 这样的方法

AuthorizationServerConfig.java

@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
    endpoints.authenticationManager(authenticationManager)
            .allowedTokenEndpointRequestMethods(HttpMethod.GET, HttpMethod.POST)
            .tokenEnhancer(new CustomTokenEnhancer());
}

【讨论】:

    【解决方案2】:

    Bhanuprakash,我有类似的问题,但我暂时这样做了:

    在“loadUserByUsername”方法中这样写:

    HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest(); System.out.println("compnayId:" + request.getParameter("companyId"));

    我认为有一个更优雅的解决方案,但我暂时使用了这个。

    谢谢。

    【讨论】:

      【解决方案3】:

      这条评论非常适合我!

      HttpServletRequest 请求 = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest(); System.out.println("compnayId:" + request.getParameter("companyId"));

      【讨论】:

      • 这并没有提供问题的答案。您可以将其作为评论留下。
      猜你喜欢
      • 2021-06-02
      • 2018-10-07
      • 1970-01-01
      • 1970-01-01
      • 2013-09-01
      • 2011-03-06
      • 2021-02-27
      • 2020-08-22
      • 2012-01-04
      相关资源
      最近更新 更多