首页 > 解决方案 > 将 LexikJWTAuthenticationBundle 与 LDAP 提供程序一起使用

问题描述

我有一个使用 Symfony API 平台的项目。我想在我的项目中使用 LexikJWTAuthenticationBundle,但我的用户存储在 Active Directory 中,所以我设置了一个 LDAP UserProvider。我试图结合以下两个文档的设置但没有成功:

这是我所做的

在 security.yml 中:

security:
    providers:
        my_ldap:
            ldap:
                service:     Symfony\Component\Ldap\Ldap
                base_dn:     OU=organization_unit,DC=domain,DC=local
                search_dn:   "OU=organization_unit,DC=domain,DC=local"
                search_password: '%env(resolve:LDAP_PASSWORD)%'
                default_roles: ROLE_USER
                uid_key: uid
firewalls:
    login:
        pattern:  ^/api/login
        stateless: true
        anonymous: true
        json_login:
            provider: my_ldap
            check_path:               /api/login_check
            success_handler:          lexik_jwt_authentication.handler.authentication_success
            failure_handler:          lexik_jwt_authentication.handler.authentication_failure

    api: 
        pattern:   ^/api/
        stateless: true
        guard:
            provider: my_ldap
            authenticators:
                - lexik_jwt_authentication.jwt_token_authenticator

在 services.yml 中:

Symfony\Component\Ldap\Ldap:
    arguments: ['@Symfony\Component\Ldap\Adapter\ExtLdap\Adapter']
Symfony\Component\Ldap\Adapter\ExtLdap\Adapter:
    arguments:
        -   host: '%env(resolve:LDAP_HOST)%'
            port: 636
            # encryption: tls
            options:
                protocol_version: 3
                referrals: false

但是当我尝试使用以下内容将请求发送到 my_domain/api/login_check 时:

{
  "username": "my_user",
  "password": "my_password"
}

我收到此错误作为响应:

{"code":401,"message":"Invalid credentials."}

标签: ldaplexikjwtauthbundlesymfony-4.4

解决方案


我通过使用自定义操作来解决我的问题,该操作使用 LDAP 检查用户是否存在并获取其角色。然后,如果新检索到的用户被授权使用该应用程序,我将创建一个新令牌并在响应中返回它。最后,令牌用于对用户对 API 的每次调用进行身份验证。

这是我的security.yml

providers:
    # provider to retrieve user from LDAP
    my_ldap:
        id: App\Security\LdapService
    # provider to retrieve user from user
    jwt:
        lexik_jwt:
            class: App\Security\User
firewalls:
    login:
        pattern:  ^/api/login
        stateless: true
        anonymous: true
api: 
        pattern:   ^/api/
        stateless: true
        guard:
            provider: jwt
            authenticators:
                - lexik_jwt_authentication.jwt_token_authenticator

控制器中的登录操作:

/**
 * @Route("/api/login", name="api_login", methods={"POST"})
 */
public function loginCheck(Request $request, LdapService $ldapService, AuthenticationSuccessHandler $authenticationSuccessHandler, AuthenticationFailureHandler $authenticationFailureHandler){
    $content = json_decode($request->getContent());
    $response= new JsonResponse();
    try{
        $user=$ldapService->authenticate($content->username, $content->password);
        return $authenticationSuccessHandler->handleAuthenticationSuccess($user);
    }catch(AuthenticationException $e){
        return $authenticationFailureHandler->onAuthenticationFailure($request, $e);
    }        
    return $response;    
}

推荐阅读