Windows Authentication is failing for IBM Cognos (Solved)

IBM’s Cognos Business Intelligence software relies on IIS for front-end publishing and authentication. If you are prompted to enter your credentials to access Cognos website or administrator console, it means Windows Authentication is failing for IBM Cognos. Here is what to do in this case.

Windows Authentication is failing for IBM Cognos
Windows Authentication prompt

Background

One of the ways to host Cognos BI is to use IIS. By configuring Windows Authentication in IIS, you can allow users to access Cognos without typing any credentials. This SSO (Single Sign-on) access requires certain steps to be followed as explained here and here.

If any of the settings are missing, you may come across an annoying prompt to enter your credentials. It quickly becomes cumbersome to enter your information every time you access to Cognos website.

Are you receiving Secure Channel (schannel) errors? Check these posts out.

Steps to follow when Windows Authentication is failing for IBM Cognos

Make sure that you review the steps in the IBM documentation to configure IIS (Links are above). In addition to the instructions, there are a few more things to check to solve this issue.

Solution 1

A common solution to this issue is that adding website’s domain name into the Intranet Zone of Internet Explorer as pointed out in a Microsoft support document:

Internet Explorer must consider the requested URL to be on the intranet (local). If the computer name portion of the requested URL contains periods (such as http://www.microsoft.com and http://10.0.0.1), Internet Explorer assumes that the requested address exists on the Internet and does not pass any credentials automatically.

Internet Explorer May Prompt You for a Password

Solution 2

Windows Authentication is performed by using either NTLM or Kerberos (preferred). Kerberos relies on SPNs (Service Principal Names) to operate. If there are no SPNs or there are duplicate SPNs for your domain, this might be the reason why Windows Authentication is failing for IBM Cognos. as explained in this article.

Follow the steps below to find and remove duplicate SPNs:

  1. Check current SPNs

    Run this at Command Prompt: setspn -F -q /cognosdev
    If it doesn’t bring any records or if it brings duplicate records, Kerberos authentication may not work with Cognos. In this case, continue with the following steps. Otherwise, do not perform the steps below.

    For example: The command may bring a result like the one below. There are duplicate records (in bold) which should be fixed.

    Checking forest DC=MyDomain,DC=com
    CN=MyDomainUser,CN=Users,DC=MyDomain,DC=com
    HTTP/MyReportServer
    HTTP/MyReportServer.MyDomain.com
    CN=MYREPORTSERVER,CN=Computers,DC=MyDomain,DC=com
    WSMAN/MyReportServer
    WSMAN/MyReportServer.MyDomain.com
    TERMSRV/MYREPORTSERVER
    TERMSRV/MyReportServer.MyDomain.com
    RestrictedKrbHost/MYREPORTSERVER
    HOST/MYREPORTSERVER
    RestrictedKrbHost/MYREPORTSERVER.MyDomain.com
    HOST/MYREPORTSERVER.MyDomain.com
    Existing SPN found!

  2. Remove duplicate SPNs (if there are any)

    Run the commands below to remove duplicate SPNs in the example above.

    setspn -d http/MyReportServer.MyDomain.com MyDomainUser
    setspn -d http/MyReportServer MyDomainUser

  3. Add new SPNs (if needed)

    Run the following commands to get the Service Principal Name added to the Web Application Pool Account:

    Setspn -f -s http/cognosdev.domain.com domain\cognosadmin
    Setspn -f -s http/cognosdev domain\cognosadmin


    Add this line to the Windows Authentication tag in the applicationHost.config file (under System.WebServer heading): 

    useAppPoolCredentials=”true”

    Save the file and run iisreset

Note: You may also want to check your load balancer settings as a misconfigured load balancer can change NTLM token transmitted through. An edited NTLM token will break windows authentication.

References

IIS is logging 200 instead of 404 status code

When you try to access a web page that doesn’t exist, browser shows 404 HTTP status code. However, you may see 200 instead of 404 status code in IIS logs. 

Here is the line from my IIS logs. This is actually a failed request that displayed “404 Page not Found” error to the user.

2018-11-27 17:32:28 ::1 GET /app1/kkrr1 – 80 – ::1 Mozilla/5.0+(Windows+NT+10.0;+WOW64;+Trident/7.0;+Touch;+rv:11.0)+like+Gecko – 200 0 0 0

Looking for a way to determine user browsers from IIS logs? Check this post out.

What to do if you see 200 instead of 404 status code

The root cause -in my case- is the custom error configuration in the web.config file. I have the configuration below that redirects users to a custom page when there is a 404 error.

<httpErrors existingResponse="Replace" defaultResponseMode="Redirect" errorMode="Custom">
     <remove statusCode="404"/>
     <error statusCode="404" responseMode="ExecuteURL" path="/index1.htm"/>          
</httpErrors>

Once I changed ExecuteURL to Redirect in the responseMode attribute, IIS started logging 404 errors.

<httpErrors existingResponse="Replace" defaultResponseMode="Redirect" errorMode="Custom">
     <remove statusCode="404"/>
     <error statusCode="404" responseMode="Redirect" path="/index1.htm"/>          
</httpErrors>

IIS log that shows the correct status code (404) after the change:

2018-11-27 17:33:25 ::1 GET /app1/oopp – 80 – ::1 Mozilla/5.0+(Windows+NT+10.0;+WOW64;+Trident/7.0;+Touch;+rv:11.0)+like+Gecko – 404 0 2 46

200 instead of 404
Incorrect (first line) and correct (second line) status codes

Background

As mentioned in this blog post, responseMode=”ExecuteURL” executes the URL in the custom error configuration sends the response to the user Therefore, IIS logs 200 instead of 404 status code. However, responseMode="Redirect” send 302 response with the custom error page URL to the user. User’s browser makes another request to the given URL.

responseMode=”ExecuteURL”
    – path is treated as URL to execute. Response returned by executing the URL is returned to client as response. On successful child execute, client will see a 200 response. Child request will enter the pipeline in the same worker process. If this request is supposed to be executed by some other application pool, IIS core will generate 403.14. When child execute produce some other error, that error code along with child execute response is returned.
    – If path starts with “http://”, exact URL specified by path is executed. Hostname has to be current hostname. Else server will produce 404.
    – When path starts with “/”, it is assumed as URL for the current site and do a child execute on that.
    – If path doesn’t start with “/” or “http://”, server will produce 404 when trying to execute the URL.

responseMode=”Redirect”
    – Custom error module blindly uses the path as location header value and send a 302 response. If path is set to “/otherpath/otherpage.htm”, this will be used as the destination and most browsers send this request back to the same host. If you set path to www.iis.net, browsers do the right thing and send the new request to www.iis.net instead.
    – IIS doesn’t handle application relative paths both for “Redirect” and “ExecuteURL” as handled by Asp.Net (e.g.  ~/error/404.htm).

Source

Still having the issue?

As a generic solution, adding the line below into the custom error page should solve the issue. Make sure to change the file extension to aspx (For example: 404.aspx).

<% Response.StatusCode = 404; %>

Multiple identical logs in Advanced Logging

Logging two events instead of one is by-design for Advanced Logging extension. Advanced Logging extension subscribes to GENERAL_REQUEST_START event in the pipeline. Whenever this event is called, a new log is recorded.

Check your Failed Request Tracing (FREB) logs. If oyu see that there are child requests, It is expected from Advanced Logging to log more than one records for the same request (More about child requests).

On the other hand, IIS logs works differently. They are based on HTTP.sys kernel driver which creates notifications only when a response is submitted. Therefore, there is one record per request in IIS logs.

Starting with IIS 8.5, Advanced Logging module is no longer available. It was integrated in the logging infrastructure of IIS server. So that this issue won’t happen in IIS 8.5 and newer versions. If you are using IIS 8.0 or a lower version, it is recommended to upgrade it.

References

Configure IIS to ignore web.config files in application subfolders

You may want to consolidate your application’s settings in one web.config file. However, the web.config files in subfolders can override the settings of the parent folder. In order to prevent it, you need to configure IIS to ignore web.config files in application subfolders. 

Here is an example of the configuration hierarchy of IIS. Note that there is a website called Site1. This website has two subfolders: SubDir1 and SubDir2 (assuming that the root application is used).

Ignore web.config files in application subfolders
IIS configuration hierarchy

Looking for a way to prevent settings to be overridden by web.config? Check this post out.

How to ignore web.config files in application subfolders

Let’s say you don’t want the web.config files in SubDir1 and SubDir2 folders to override settings in the web.config file of Site1 folder. In order to achieve it, use allowSubDirConfig attribute in your applicationHost.config file. Here is an example:

<sites>
   <site name="Site1" id="1">
      <application path="/">
         <virtualDirectory path="/" physicalPath="D:\WebApps\Site1" allowSubDirConfig="false" />
      </application>
   </site>
</sites>

If you want this settings to be effective in all websites hosted by IIS, use virtualDirectoryDefaults tag:

<sites>
   …
   <virtualDirectoryDefaults allowSubDirConfig="false" />
</sites>

Note: allowSubDirConfig attribute can be used only in applicationHost.config. It is not available for web.config files (Source).

Ignore web.config for certain subfolders only

It is also possible to ignore web.config files in certain subfolders only. However, these folders has to be virtual folders. In the example below, web.config files are ignored in all subfolders except the one in subDir2.

<sites>
   <site name="Site1" id="1">
      <application path="/">
      <virtualDirectory path="/" physicalPath="D:\WebApps\Site1" allowSubDirConfig="false" />
      <virtualDirectory path="/SubDir2" physicalPath="D:\WebApps\Site1\SubDir2" allowSubDirConfig="true" />
      </application>
   </site>
</sites>

Please note that I am using <application path="/"> in the examples above. This is the root application which is created when you add a new website. If you have a specific application, make sure to use it in your config files.

Disable inheritance

What if you want to allow web.config files to be used in subfolders but you don’t want certain settings to be inherited by subfolders? 

For example, your root web.config says the only default document is index.htm. However, your subfolder web.config says the only default document is iisstart.htm. If there is no such file iisstart.htm in the subfolder, root setting which is index.htm will be inherited and used. If you want to prevent root settings to be inherited, use inheritInChildApplications attribute in location tag.

<location path="" inheritInChildApplications="false">
   <system.webServer>
      <defaultDocument enabled="true">
         <files>
            <add value="index.htm" />
         </files>
      </defaultDocument>
   </system.webServer>
</location>

The location path in the example above is empty. It means that this setting will be applied to the level of the config file and below.

More information about inheritInChildApplications: Link 1 and Link 2

References