HackerOne users: Testing against this community violates our program's Terms of Service and will result in your bounty being denied.

SSO for API v2

Is there any sso method for API v2. For example, create a temporarily user and return an access token for the user by passing the admin token and user email/userID. If there isn't, what's the alternative way to achieve? Thanks in advance

Comments

  • R_JR_J Ex-Fanboy Munich Admin

    I don't think that's the question you really wanted to ask. But if you think so, here is the answer: no, there is no single "sso method". There are standard sso solutions integrated. If you want to use them, your script must speak those standards, too.

    Otherwise you would have to create your own custom authenticator. Take a look at /library/core/class.oauth2.php to get an impression what must be done for that. But in order to create a custom authenticator, you should have deeper Vanilla knowledge. Since you haven't stated anywhere which connectors there are on the side of your application, I think those need to be implemented, too.

    If you want to emmit an api token by code, take a look at that example implementation.


    But as I said: I don't think that is what you are looking for. Instead you seem to only want to integrate a forum on your page, nor?

    Currently, I'm looking for a solution to integrate vanilla forum into my application with our own user database. I'm trying to use API at first but then I couldn't found any easy solution for SSO (couldn't fully understand how connectjs works).


    The documentation has two interesting statements about jsConnect:

    If you have a website that stores your user’s identity and the only thing you need to integrate is a forum, jsConnect is a far simpler solution

    jsConnect is the way to go for you, I'd say.


    However, even our easier solution does require a developer on your team. A developer can typically set up the client side of jsConnect in 2-6 hours using our technical documentation.

    So take your time to read the documentation :


  • MunSemMunSem New
    edited December 2019

    Hi @R_J , really appreciate spending time explain to me.

    Please correct me if I'm wrong about jsConnect.

    Step to correctly configure jsConnect

    1. Create an endpoint at server-side (using one of those example libraries) which need to pass in user info as parameter and return a jSONP format response.
    2. enabled jsConnect plugin in my dashboard
    3. in jsConnect plugin, generate clientID and secretID and put in the endpoint URL

    After all these configuration, I still have no idea how can I call API on behalf of user. How do I get the access_token?

  • R_JR_J Ex-Fanboy Munich Admin

    Sounds reasonable, but I never used jsConnect, therefore I'm not the best one to give advices. @donshakespeare seems to be the expert.

  • Enters expert ....

    Exits ...

    Comes back in..

    @MunSem look here https://open.vanillaforums.com/discussion/comment/258764/#Comment_258764

    You shall find the integration a breeze. jsConnect is low key and simple and minimally hazardous to one's health.

    Feel free to ask more questions about your particular case (after reading that link)

    Cheers.

  • Just to make the whole concept clear. Isn't mean that user can access POST api without access_token after user manage to login using jsconnect?

  • jsConnect only just creates a user within Vanilla DB via mother site. It will not bypass any thing.

    Any user account created via jsConnect can do anything a regular user can.

    So, you might need to go to "edit profile" to generate access_token.

  • is that means there's still no way to access POST api on behalf of normal user programmatically?

  • R_JR_J Ex-Fanboy Munich Admin

    Are you joking or trolling? Please reread everything you have been told. Read the docs. Take a look at the API methods.

    Everything has been said before.

  • HI @R_J , I'm sorry if I misunderstand. My requirement is to create a forum using vanilla API in my own website.

    Whenever our client login to our website, they should have already login to the forum and call any API they want (including create discussion/ comment). That is why I need SSO. I'm confused because @donshakespeare stated at the last comment

    So, you might need to go to "edit profile" to generate access_token.

    When our client login to our website, we don't expect our client manually go to their profile and generate access_token input to us. Once again apologize if I confused you guys.

  • R_JR_J Ex-Fanboy Munich Admin

    Okay. Understood. Then read what has been written above (about how to create a token for a user). Read the docs. Take a look at the API methods.

    Everything has been said before.


    I gave you an example above which shows how to create a token. You will need a table with user ids from your page and user ids from Vanilla. I think it logically belongs to the "master" application, which is your app.

    So if your own id in your app is munsem@example.com and your user id in Vanilla is 42, and you are logged in your app as MunSem and want to access the forum, you need to emmit a token for user app user MunSem = vanilla user id 42 if you want to access the forum as MunSem.

    Just in case you missed it because it was kind of hidden behind a link for your eyes: that's the code to create a token that I have linked o above (I just have replaced some soon-to-be-deprecated methods):


    // Check if there is already such a token for this user.
    $accessTokenModel = new AccessTokenModel();
    $accessToken = $accessTokenModel->getWhere(
       [
           'UserID' => $userID,
           'Type' => Gdn::config('apitoken.name'),
           'DateExpires >=' => DateTimeFormatter::timeStampToDateTime(time())
       ]
    )->firstRow(DATASET_TYPE_ARRAY);
    if ($accessToken == []) {
       // Issue new token if needed.
       $token = $accessTokenModel->issue(
           $userID,
           Gdn::config('apitoken.expires'),
           Gdn::config('apitoken.name'),
           explode(',', Gdn::config('Apitoken.scope'))
       );
    } else {
       // If oken exists, sign with expiry date.
       $token = $accessTokenModel->signToken(
           $accessToken['Token'],
           $accessToken['DateExpires']
       );
    }
    


    But since there is no real connector between both databases changes to users from your app will not be applied to Vanilla. You have to take care for something like that by yourself (e.g. in case of a user changing his mail address).

  • Thanks @R_J :D

    But if I'm not mistaken AccessTokenModel only available in php. Where can i find AccessTokenModel in other language? or just a standard jwt token?

  • R_JR_J Ex-Fanboy Munich Admin

    But if I'm not mistaken AccessTokenModel only available in php.

    You've nailed it! 🥂


    Where can i find AccessTokenModel in other language?

    Think about the above "But if I'm not mistaken AccessTokenModel only available in php." Now simply try to answer that question by yourself.


    or just a standard jwt token?

    Back to the docs: https://success.vanillaforums.com/kb/articles/31-sso-overview

    There's nothing said about JWT here (to be honest, at a different place in the docs you would be able to read about JWT but it's only for the hosted forum customers)


    So no matter how often you ask for it: without writing a PHP plugin for Vanilla on your own, you will not be able to proceed. So stop asking and start coding

  • If you think I'm trying to be lazy, I'll tell you I'm not.

    You told me jsConnect is better to use in my case and now you're telling me to write a PHP plugin for vanilla. That's why I'm so confused.

    But I really appreciate your time explain to me. I guess I have to stop here.

    Thanks once again.

  • charrondevcharrondev Developer Lead (PHP, JS) Montreal Vanilla Staff

    @MunSem This has been a complicated topic for a while.

    We have some old endpoints that were in progress (/api/v2/authenticate ) but they were removed from the roadmap. They exist behind a feature flag now. You can enable them by adding the following configuration flags:

    $Configuration['Feature']['AuthenticationAPI']['Enabled'] = true;
    

    Unfortunately it's not really well documented and only works with password authentication and JSConnect.

    OAuth token exchange

    If you use OAuth, we have recently created a token exchanging endpoint:

    You can see the PR here:

    In this setup if you have some OAuth SSO configured, you will be able to exchange an OAuth token for a Vanilla access token.

  • Some nice topics


    /* Informations sur l'authentification */
    
    $timestamp = time(); 
    $username = "your_admin_username"; 
    $method = array("users","configuration","roles"); //discussions, etc ...
    
    $request_authentication = array(
    	'username' => $username, 
    	'timestamp' => $timestamp);
    
    ksort($request_authentication);
    $request_authentication = implode('-', $request_authentication);
    $secret_code = 'xxxx... '; //Code secret de l'API
    $token = hash_hmac('sha256', strtolower($request_authentication), $secret_code);
    $data = array('Name'=>'Test',
                  'Email'=>'test@mail.fr',
                  'Password'=>'pass',
                  'RoleID'=> [8]);
    $header = array('Content-Type: application/json',
    				 'Accept: application/json');
    
    /* Construction de l'URL */
    $url = "http://YOURURL/forum/api/".$method[0]."?username=$username&timestamp=$timestamp&token=$token" ;
    
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true );
    curl_setopt($ch, CURLOPT_POST, count($data) );
    curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data) ); 
    curl_setopt($ch, CURLOPT_HTTPHEADER, $header); 
    $result=curl_exec ($ch);
    
    echo $result;
    
  • I got the same issues, your can type to use this https://codeofaninja.com/2018/09/rest-api-authentication-example-php-jwt-tutorial.html

    I am not a programmer, I am a industrial designer (with 0 knowledge of code), I follow the tutorial step by step. and I changed the code based on the database parameters, like firstname -> Name, Id -> UserID, etc. and I can (the users) generate a string of JWT token with their email and password, but the JWT cannot control the apiV2.

    I will try to use the JWT to an temp Vanilla Token, use the temp Vanilla Token to genarate a real Vanilla Token, and use the real Token to connect to the apiV2.


    The token will store in user side.

Sign In or Register to comment.