Row based security based on email and company and SSO



  • Avatar
    Malinda Jepsen


    We have a very similar scenario in our environment. Our SSO code performs this mapping when the user accesses our Sisense app. This is because we can't just do it when the user is created, their security can change over time. 

    Inside our SSO code, we use the API to set the user's security.  Like you, I have two levels of security.  I added "Data Security" to the cube (or set in our case) for each level.  Our code actually handles creating the user and adding the security and then they are logged in. We were able to do this because they launch our Sisense application from within our application and this code runs on the "on click" event.


    Comment actions Permalink
  • Avatar
    Alistair Broom

    Hi Malinda,


    Thank you for your response.  I was worried that I was asking to do something that either wasn't possible or nobody has done before.

    Your implementation sounds exactly like the way I would like to go about this.

    I may be asking liberties here, but is there any way you would be able to share the code snippet with me that calls the API and adds the user and sets security please.  I have a deadline of Monday to get this all up and running and any shortcuts or help I can get would be very much appreciated.  Also Friday the main web application developer is in the office to apply changes to our main system, and hopefully I could get him to add this code at the same time.

    Don't worry if you are not in a position to share the code.  I am happy that I have some direction on the method I can use to achieve this.

    Many Thanks



    Comment actions Permalink
  • Avatar
    Malinda Jepsen

    This is a stripped down LINQPad script, so it's not production code, but it shows the concepts. Also, this is for pre 7.2, so I know that you need to make a change to include the Bearer now. We are also using JWT, not SAML. I would post a ticket to support and let them know it's time critical. They may be able to help you through the final details.

    public class SisenseJwtSample
    public SisenseJwtSample()
    public void SisenseUsersRest(HttpContext context)
    TimeSpan t = (DateTime.UtcNow - new DateTime(1970, 1, 1));
    int timestamp = (int)t.TotalSeconds;
    var payload = new System.Collections.Generic.Dictionary<string, object>() {
    { "iat", timestamp },
    { "email", "<email>" },
    { "password", "<password>" },
    // NOTE: we found that this is still optional in
    //{ "jti", "abcdef" } -- supposedly this version doesn't work with jti... but it looks like it does here!
    // Optional properties
    //{ "exp", (int)t.AddMinutes(30).TotalSeconds }, // Expiration time
    //{"aud", new string [] {"sisense" } } // A collection of audience strings OR a single string. must contain the string "sisense"

    // you can find the Rest API Token on the REST API page when logged in as an admin
    string token = JWT.JsonWebToken.Encode(payload, "<RESTAPIToken>", JWT.JwtHashAlgorithm.HS256);
    WebClient _client = new WebClient();

    _client.Headers["X-API-KEY"] = token;

    // NOTE: this does NOT work: get a 403 forbidden
    // to test: remove the X-API-KEY from the header and just uncomment next line
    //_client.Headers["Authorization"] = "Bearer " + token;


    string responseString;
    // make the call
    responseString = _client.DownloadString("http://<server>/api/users/<some username>");
    // display results


    void Main()
    /// <summary>
    /// Summary description for SisenseJwtSample
    /// </summary>
    var httpRequest = new HttpRequest("", "http:/<servername>", "");
    var stringWriter = new StringWriter();
    var httpResponse = new HttpResponse(stringWriter);
    var httpContext = new HttpContext(httpRequest, httpResponse);

    var sessionContainer = new HttpSessionStateContainer("id", new SessionStateItemCollection(),
    new HttpStaticObjectsCollection(), 10, true,
    SessionStateMode.InProc, false);

    httpContext.Items["AspSession"] = typeof (HttpSessionState).GetConstructor(
    BindingFlags.NonPublic | BindingFlags.Instance,
    null, CallingConventions.Standard,
    new[] {typeof (HttpSessionStateContainer)},
    .Invoke(new object[]{ sessionContainer});

    HttpContext.Current = httpContext;
    var sisensecall = new SisenseJwtSample();



    Comment actions Permalink
  • Avatar
    Malinda Jepsen

    Apologies, that code wasn't complete with the data security. We are using api/users to create the user and the api/elasticubes/datasecurity endpoint to do the datasecurity set up for each user (v .9).

    Here's the structure for the data security:

    new SisenseDataSecurity {
    column = "colname",
    datatype = "text",
    elasticube = string.Empty,
    members = "string of email address for example",
    server = ServerName,
    shares = new List<SisenseShares> { new SisenseShares { party = sisenseUserId, type = "user" } },
    table = "tablename",

    Comment actions Permalink
  • Avatar
    Alistair Broom

    Thank you so much for your help with this.  My main app dev guy says he can sort this tomorrow now.

    Again thank you so much for your help.

    Comment actions Permalink

Please sign in to leave a comment.