okta / okta-sdk-php

PHP SDK for the Okta API
Apache License 2.0
38 stars 71 forks source link

Create user with hashed password #136

Closed baruchespinoza closed 2 years ago

baruchespinoza commented 2 years ago

Hello, i'm creating this issue because i can't find a way to create a user with a hashed password.

I'd expect it to work somewhat like this:

$user = new \Okta\Users\User();

$credentials = new \Okta\Users\UserCredentials();

$password = new \Okta\Users\PasswordCredential();
$password->setHash('$2y$10$6bRY5NVVBYUObrDS1ml5gUj5uzXQ5scmiXQS3gYLin'); // This doesn't work

$credentials->setPassword($password);
$user->setCredentials($credentials);

I can achieve this through the HTTP api, i'd expect the SDK to include a way to do it as well.

Maybe i'm missing something?

If this feature is not implemented yet, is there a plan to do it in the future?

bretterer commented 2 years ago

@baruchespinoza This feature is not implemented in our PHP SDK. Currently there are no plans here to implement this feature in the PHP SDK either.

Currently, the only option for implementing this feature for you to get unblocked would be make the API calls directly, using the features of the SDK.

Your method can be set up to make the API calls using the DataStore and RequestExecutor. Just take a look at the existing methods and you should be able to do essentially the same. Sorry we don't have this set up and it is causing you some friction.

Please let us know if you run into any issue with your patch.

baruchespinoza commented 2 years ago

I'll leave my solution here in case someone else runs into this issue, turns out this can be accomplished with the SDK with just a few tweaks

$user = new \Okta\Users\User();
$profile = new \Okta\Users\UserProfile();

$profile->setFirstName($name)
    ->setLogin($userName)
    ->setMobilePhone($phoneNumber)
    ->setEmail($email);

$user->setProfile($profile);

$credentials = new \Okta\Users\UserCredentials();
$credentials->setProperties((object) [
    'password' => [
        'hash' => $this->formatHashedPassword('$2a$10$g6L4T3YHhrNdLdmoOJ/pHuSPROae9C2/1iB/Alz1LtcyKe32EEasW')
    ]
]);

$provider = new \Okta\Users\AuthenticationProvider();
$provider->setName('OKTA')->setType('OKTA');
$credentials->setProvider($provider);

$user->setCredentials($credentials);

$user->create();
baruchespinoza commented 2 years ago

I forgot to include this function as well:

/**
 * @param string $hashedPassword
 *
 * @return array A bcrypt password broken into it's components
 */
public function formatHashedPassword(String $hashedPassword): Array
{
    $passwordParts = explode('$', $hashedPassword);
    $workFactor = $passwordParts[2];
    $hash = substr($passwordParts[3], 0, 22);
    $value = substr($passwordParts[3], 22);
    return [
        'algorithm' => 'BCRYPT',
        'workFactor' => $workFactor,
        'salt' => $hash,
        'value' => $value,
    ];
}
artur-bartlinski commented 2 years ago

@baruchespinoza It doesn't work for me if I use SHA-512 algorithm. The user is created in Okta, but I cannot sign in with my password.

The password was created using the crypt function.

$salt = '$6$rounds=1000$' . 'my-salt' . '$';
$password = crypt('my-password', $salt)
return [
        'algorithm' => 'SHA-512',
        'saltOrder' => 'PREFIX',
        'salt' => $salt,
        'value' => $password,
    ];

I am not sure what 'salt' and 'value' should be set to. Any help is much appreciated.

rossb-dlx commented 2 years ago

This one seems to work for me:

class HashedPasswordCredential extends \Okta\Users\PasswordCredential
{
    const HASH = 'hash';

    public function getValue()
    {
        return $this->getProperty(self::HASH);
    }

    public function setValue($value)
    {
        $this->setProperty(
            self::HASH,
            $value
        );
        return $this;
    }
}

Then set the hashed password

$creds = new \Okta\Users\UserCredentials();
$pw = new HashedPasswordCredential();
$pw->setValue([
    'algorithm' => 'BCRYPT',
    'workFactor' => $workFactor,
    'salt' => $salt,
    'value' => $hashedPassword,
]);
$creds->setPassword($pw);