【问题标题】:Spring Authentication against an external API针对外部 API 的 Spring 身份验证
【发布时间】:2016-01-17 10:17:41
【问题描述】:

我需要针对外部 API 对用户进行身份验证,在该 API 中我需要传递 用户名密码。该 API 是一个 REST Web 服务,它将返回一个 json 对象。现在我需要提取“auth_token”(json 中的一个元素)并将其设置在用户上下文中以供进一步请求因为其他请求需要将此 auth_token 设置到标头中 .在我们端不需要编写身份验证逻辑。所有登录逻辑都在 API 端处理。 返回的 JSON 对象如下所示:

{
  "success" : true,
  "auth_token" : "a2xvv-mqe_sV_Lhsggkd3Q",
  "email" : "****.***@***.com",
  "role" : "admin",
  "time_zone" : "Mumbai",
  "user_key" : "b3222tf92d",
  "sign_in_count" : 208,
  "organisation" : {
    "name" : null,
    "organisation_key" : null,
    "license" : {
      "license_key" : "tebde23823t5a76828e2et8683fd3b33e2eat5fb"
    }
  }
}

如何在 Spring Security 中实现这个功能。 如果可能的话,如果您向我提供示例步骤,那将是一个很大的帮助。

【问题讨论】:

    标签: java spring rest spring-security


    【解决方案1】:

    您没有说明如何在应用中获取用户凭据。我假设你有一个登录表单。

    如果这是你的场景,那么你可以配置 Spring Security 来管理这个登录表单。 Spring 将以UsernamePasswordAuthenticationToken 的形式获取用户凭据。

    然后你可以创建一个自定义的org.springframework.security.authentication.AuthenticationProvider 并覆盖这个方法:

    public Authentication authenticate(Authentication);
    

    在此方法中,您可以提取用户凭据并使用您提到的 REST Web 服务

    获得REST Web 服务 响应后,您可以使用AuthorityUtils 完成UsernamePasswordAuthenticationToken。我在显示的 json 中看不到角色、组或类似内容,我想您可以从任何地方获取此信息。

    这样,您将使用有效的SpringSecurityContext 覆盖authenticate 方法并满足您的需求。

    希望对你有帮助!

    编辑

    为了回答评论,我放了一个 auth 方法的示例:

    @Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException {
        UsernamePasswordAuthenticationToken token = null;
        Authentication result = null;
        User user = null;
    
        token = (UsernamePasswordAuthenticationToken) authentication;
    
        if (token != null) {
          if (StringUtils.isNotEmpty(token.getName())) {
    
            if (YOUR_AUTH_METHOD(token.getName(), (String) token.getCredentials())) {
    
                    //DO what you want to retrieve authorization
    
                    String[] auxAuth = new String[size];
    
                    //Put your roles, groups, ... into auxAuth
          //Role names must be ROLE_XXXXX
    
                    result = new UsernamePasswordAuthenticationToken(
                        token.getName(), token.getCredentials(),
                        AuthorityUtils.createAuthorityList(auxAuth));
                }
            }
        }
    
        return result;
    }
    

    使用此方法您检索spring token,然后获取登录名和密码。最后,它管理用户授权的角色,然后为 Spring Security Context 构建一个有效的令牌。

    【讨论】:

    • 我已经实现了这个方法并且也消费了这个服务。我也得到了身份验证令牌。但是正如您所说的要完成“UsernamePasswordAuthenticationToken”,由于没有构造函数来设置令牌,该怎么做?在哪里设置我得到的 Auth_Token。?
    【解决方案2】:

    您应该实现自己的 AuthenticationProvider 并在 beans 文件中“注入”它。

    下面是示例类的摘录:

    public class LdapAuthProvider implements AuthenticationProvider {
    
    @Override
    public Authentication authenticate(Authentication authentication)
            throws AuthenticationException {
    
            UserDetails user = userDetailsService.loadUserByUsername(username);
            UsernamePasswordAuthenticationToken result = new UsernamePasswordAuthenticationToken(user,
                    authentication.getCredentials(), user.getAuthorities());
            result.setDetails(authentication.getDetails());
            return result;
    }
    
    @Override
    public boolean supports(Class<?> authentication) {
        return (UsernamePasswordAuthenticationToken.class.isAssignableFrom(authentication));
    }
    
    }
    

    然后你需要像这样将它注入到 AuthenticationManager 中:

    <authentication-manager alias="authenticationManager">
        <authentication-provider ref="ldapAuthProvider"/>
    </authentication-manager>
    

    上面的响应假设您了解 Spring 中的基本安全性(用户详细信息、身份验证令牌、身份验证管理器)。如果没有,请先阅读Spring Security docs

    【讨论】:

    • 方法 userDetailsS​​ervice.loadUserByUsername(username) 中的“用户名”字段来自哪里??
    • @MayurGupta 它来自身份验证类。 String username=(String)authentication.getPrincipal();
    【解决方案3】:

    您可以实现自定义AuthenticationProvider。有关详细信息,请参阅this blog post

    【讨论】:

      猜你喜欢
      • 2020-07-10
      • 1970-01-01
      • 2017-09-28
      • 2017-10-08
      • 2020-12-12
      • 2018-05-18
      • 2020-07-29
      • 1970-01-01
      • 2011-08-03
      相关资源
      最近更新 更多