Implementing custom authentication and authorization with Power BI Report Server

PowerBI is a the new Microsoft product for the reports design and deployment, composed by a server part that can be on cloud or On-Premise and PowerBI Desktop that is the client used to design the reports.

The Report Server (On-Premise) consists in web based interface to access and visualize the reports, protected by an authentication layer that need to be configured; we have two options about that, the first one is using our LDAP directory and enable the windows authentication; the second one is configure a custom authentication and implementing a piece of code (or use an existing one) that authenticate the user on the company directories.

In order to implementing the custom authentication, we have some steps to do about the code development and others about the server configuration.

Code development

We can start by downloading the Microsoft custom security sample project from GitHub.

In this project we’ll find a Logon.aspx page:

The page has the user and password fields and two buttons about the login and the user registration; for example we can change the look and feel of the page based on company brand.

We can put our custom authentication in the method invoked by the login button, in the Logon.aspx.cs file:

Instead of the VerifyPassword method we can put a call, for example, to an our web api authentication method and validate the credentials.

Another use case is call Power BI from and external application where the user is already authenticated; the user shouldn’t relogin on power bi and the report should appear without any authentication; we can manage this by passing, for example, the authentication token in the url of the report like this:

https://PBIhostname/ReportServer/logon.aspx?ReturnUrl=/ReportServer/localredirect?url=/Reports/powerbi/report.pbix&token=123

We are calling the logon page of PBI Report Server and we are passing the ReturnUrl parameter with the url of the report and the authentication token; now we can manage this token in the PageLoad event of the Logon.aspx.cs file:

The VerifyTokenAsync method deal with the token validation, for example by calling our Web Api; if the check will be ok, then the user will be automatically redirect to the report, otherwise a new login will be needed.

Once the page layout of the login page and the authentication layer are completed, we can configure PowerBI Report Server to use the custom authentication.

Server configuration

First, we have to copy the Logon.aspx page in the ReportServer sub directory, for example:

C:\Program Files\Microsoft Power BI Report Server\PBIRS\ReportServer

Next we have to copy the dll of the project into three subfolders:

  • ReportServer\bin
  • Portal
  • PowerBI

Then, edit the RSReportServer.config file located in the ReportServer folder; we have to modify the Authentication section like this:

<Authentication>
<AuthenticationTypes>
<Custom/>
</AuthenticationTypes>
<RSWindowsExtendedProtectionLevel>Off</RSWindowsExtendedProtectionLevel>
<RSWindowsExtendedProtectionScenario>Proxy</RSWindowsExtendedProtectionScenario>
<EnableAuthPersistence>true</EnableAuthPersistence>
</Authentication>

In the Security and Authentication elements, modify the Extension element like this:

<Extension Name="Forms" Type="Microsoft.Samples.ReportingServices.CustomSecurity.Authorization, Microsoft.Samples.ReportingServices.CustomSecurity" >

Now we have to modify the RSSrvPolicy.config file located in the ReportServer subfolder as well and add a new CodeGroup element:

<CodeGroup
class="UnionCodeGroup"
version="1"
Name="SecurityExtensionCodeGroup"
Description="Code group for the sample security extension"
PermissionSetName="FullTrust">
<IMembershipCondition
class="UrlMembershipCondition"
version="1"
Url="C:\Program Files\Microsoft Power BI Report Server\PBIRS\ReportServer\bin\Microsoft.Samples.ReportingServices.CustomSecurity.dll"/>
</CodeGroup>

The last file to edit is the Web.config file, we have to change the identity element:

<identity impersonate="false" />

The authentication element:

<authentication mode="Forms">
<forms loginUrl="logon.aspx" name="sqlAuthCookie" timeout="60" path="/"></forms>
</authentication>

The authorization element:

<authorization> 
<deny users="?" />
</authorization>

The trust element:

<trust level="Full" originUrl="" />

Now the configuration is completed and after a server restart, the custom authentication will be available.

With this project we are able to customize the authorization as well; we can intercept the events about the access to resources, folders, reports and apply our business logic.

Let’s look to the changes that we have to do.

Authorization

In the project there is an Authorization.cs file with some CheckAccess methods used by PowerBI Report Server to verify if a user is authorized to do a specific operation.

We can leverage these methods to implements our custom business logic; for example che custom authentication do not allow the use of groups, we don’t have an LDAP directory, so it’s impossible to it to resolve any group; but with a piece of code and these events we can solve the problem.

Suppose to store the user tokens used in previous chapter in a txt file; then we implement a method that accept two parameters, the username and the access entry to be check:

private bool IsMember(string username, string group)
{
var path = Directory.GetParent(Path.GetDirectoryName(AppDomain.CurrentDomain.BaseDirectory)).FullName + @"\ReportServer\tokens.txt";
if (File.Exists(path))
{
var tokens = JsonConvert.DeserializeObject<List<Token>>(File.ReadAllText(path));
var token = tokens.FirstOrDefault(t => t.Username.ToLower() == username.ToLower());
if (token != null)
{
var client = new HttpClient();
client.BaseAddress = new Uri(token.UrlServerSin);
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token.Access_token);
var message = client.GetAsync(".....").Result;
if (message.StatusCode == HttpStatusCode.OK)
{
var groups = JsonConvert.DeserializeObject<string[]>(message.Content.ReadAsStringAsync().Result);
var enabled = groups.Any(g => g.ToLower() == group.ToLower());
return enabled;
}
}
}
 return false;
}

With the user token we can retrieve the user groups with our specific api and then check if the access entry is one of these.

Then, we can use this method in the events that we want to manage, for example the access of a folder:

With this change, when a user try to access to a folder where the security is defined with groups, the CheckAccess method is fired and with the custom method is checked if the user is member of a specific group.

We can do the same things for others components like reports.

Summary

The customization of the Power BI Report Server authentication allow to modify the layout of the login page, the business logic of the login phase (for example by calling a web api to login) and the business logic of the authorization mechanism.

With these elements we can customize the behaviour of the enviroment to fit to the comany requirements.

10 thoughts on “Implementing custom authentication and authorization with Power BI Report Server

Add yours

  1. Hello, first congratulations on the post, very well detailed and built. I have a question, see my scenario: I have a PHP intranet in the company that works only in the company environment behind a firewall.

    On this intranet I insert an IFRAME to incorporate some reports from the PBI Report Server, but always ask for a password that I defined as a local user.

    I really need that when accessing my page on the intranet, NO password was requested for the user. (I don’t need protection because the Firewall already does this and the data is not sensitive)

    Like

    1. Hello, you can use the custom authentication and in the Page_Load method of the logon page redirect the user to the report, or before that check a generic token authentication if you want to provide a minimal security.

      Like

  2. Hi! Thanks for answering!
    Redirecting the user directly to the report would be great, but there are several reports I have. Each area of the intranet carries a report.

    How would it be to check for generic token?
    Another question: do I need to compile something after changing it in “CustomSecuritySample” or just replace it in ReportServer Path?
    (I’m asking because I don’t know anything about ASP.NET or C #)

    Like

    1. Hi, as you can see in the post, you have to call the report with an url like this one:
      https://PBIhostname/ReportServer/logon.aspx?ReturnUrl=/ReportServer/localredirect?url=/Reports/powerbi/report.pbix&token=123

      where your report is report.pbix and the token is a generic token.
      In the page_load event of the login page you can retrieve the token with Request.QueryString[“token”], if it’s ok you have to call FormsAuthentication.Redirect…
      that will redirect automatically the navigation to the relative path specified in the url parameter of the query string.

      Like

  3. Ciao Mirko,
    prima di tutto grazie per il tuo aritcolo molto interessante.
    Nella nostra azienda abbiamo Power BI report server on premise e vorremmo usare un’autentifazione via l’LDAP aziendale.

    Con metodo descritto nel tuo articolo te é possibile?

    La gestione degli accessi ai vari reports ai vari utilizzatori é fattibile?

    Grazie e buona giornata

    Like

    1. Ciao Andrea, si nell’esperienza che ho avuto io in un’azienda cliente abbiamo prima impostato l’autenticazione windows con accesso alla active directory aziendale. Successivamente, essendo l’esigenza quella di autenticarsi su più directory LDAP siamo passati all’autenticazione custom, quindi una dll che gestisce la scansione delle varie directory aziendali. Nel vostro caso probabilmente sarebbe sufficiente l’autenticazione windows.

      Like

  4. Hi Mirko, we’ve been following your post to implement custom security on Power Bi. We integrated it with Identity Server 4 successfully. The problem we are facing now is Authorization. Our idea was to verify if user have permission to view report by calling our API from CheckAccess method. API would receive user ID and report GUID and return true or false based on what we have in DB related to user/report permissions. Currently we cannot find Report GUID user is trying to see in CheckAccess. What are we missing? Thanks a lot

    Like

  5. I have configured the Power BI Report Server for custom authentication. When we login with the custom user we get the following error. Request your help in this regard and let us know how to associate security roles to custom users

    -William Stanaland

    Like

Leave a Reply to Andrea Todaro Cancel reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

Create a website or blog at WordPress.com

Up ↑

%d bloggers like this: