keycloak realmresourceprovider corse - cross-domain

I'm evaluating some IAM Products and encountered a Problem with CORS with the RealmResourceProvider from Keycloak.
The goal is to write an angular4 client able to create user and manage groups with a REST interface from Keycloak.
Server-side:
I tried to implement the Rest interface with the RealmResourceProvider Interface in order to access Realm and User Data as easy as possible.
I followed the Beercloak example (github.com/dteleguin/beercloak) and got it working, but without a custom theme (only the REST-Resources). My own application is packaged as Jar.
I managed to call this Facade via REST Client and it worked (By calling localhost:8080/auth/realms/master/protocol/openid-connect/token first and then stuffing the Token in the Authorization-Header).
keycloak-configuration
But if i test it via Browser, I will need to enable Cross-Origin-Ressource-Sharing. In order to do that I added the 'enable-cors' attribute to the 'keycloak.json' in the server application:
{
"realm": "master",
"auth-server-url": "http://localhost:8080/auth",
"ssl-required": "external",
"resource": "pharmacyRessource",
"public-client": true,
"enable-cors": true
}
Additionally I Created a Client in the Keycloak Admin.
Client Config
Client-Side and Problem:
The angular client uses Mohuks ng2-keycloak service from github.com/mohuk/ng2-keycloak/blob/master/src/keycloak.service.ts to obtain the accesstoken. - Works fine.
But in case i make a GET-request to my Resource, the preflight fails because of missing Access-Control-Allow-Origin Header:
Error 401
The keycloak.json used for initializing the keycloak-client in javascript looks like this:
{
"realm": "master",
"auth-server-url": "http://localhost:8080/auth",
"ssl-required": "external",
"resource": "pharmacyRessource",
"public-client": true
}
My failed solutions:
I tried to implement a CORS Filter, but i didn't succeed because i
couldn't get it registered by keycloak.
I also implemented the #OPTIONS Method and appended CORSE Headers by
myself. Didn't work either, because the Method never got invoked.
I tried to package it as .war in order to enabling a custom
Filter/Provider, but failed at registering the Resources to keycloak.
My testing environment is the offical docker container from hub.docker.com/r/jboss/keycloak/

Do you need enable CORS in your keycloak server (that runs in wildlfy) . You can do it, putting the code bellow into your standalone.xml from wildfly:
<subsystem xmlns="urn:jboss:domain:undertow:4.0">
<buffer-cache name="default"/>
<server name="default-server">
<http-listener name="default" socket-binding="http" redirect-socket="https" enable-http2="true"/>
<https-listener name="https" socket-binding="https" security-realm="ApplicationRealm" enable-http2="true"/>
<host name="default-host" alias="localhost">
<location name="/" handler="welcome-content"/>
<filter-ref name="server-header"/>
<filter-ref name="x-powered-by-header"/>
<filter-ref name="Access-Control-Allow-Origin"/>
<filter-ref name="Access-Control-Allow-Methods"/>
<filter-ref name="Access-Control-Allow-Headers"/>
<filter-ref name="Access-Control-Allow-Credentials"/>
<filter-ref name="Access-Control-Max-Age"/>
<http-invoker security-realm="ApplicationRealm"/>
</host>
</server>
<servlet-container name="default">
<jsp-config/>
<websockets/>
</servlet-container>
<handlers>
<file name="welcome-content" path="${jboss.home.dir}/welcome-content"/>
</handlers>
<filters>
<response-header name="server-header" header-name="Server" header-value="WildFly/10"/>
<response-header name="x-powered-by-header" header-name="X-Powered-By" header-value="Undertow/1"/>
<response-header name="Access-Control-Allow-Origin" header-name="Access-Control-Allow-Origin" header-value="http://localhost"/>
<response-header name="Access-Control-Allow-Methods" header-name="Access-Control-Allow-Methods" header-value="GET, POST, OPTIONS, PUT"/>
<response-header name="Access-Control-Allow-Headers" header-name="Access-Control-Allow-Headers" header-value="accept, authorization, content-type, x-requested-with"/>
<response-header name="Access-Control-Allow-Credentials" header-name="Access-Control-Allow-Credentials" header-value="true"/>
<response-header name="Access-Control-Max-Age" header-name="Access-Control-Max-Age" header-value="1"/>
</filters>
</subsystem>

Keycloak should automatically handle CORS headers for you when you set "enable-cors": true in the client configuration JSON file as you mention.
The reason why the server is not adding the Access-Control-Allow-Origin header is because Keycloak rejects the origin unless the token is configured (via the admin console) to do so. It's very subtle, but it's mentioned in the docs (https://www.keycloak.org/docs/4.1/securing_apps/index.html):
enable-cors
This enables CORS support. It will handle CORS preflight requests. It will also look into the access token to determine valid origins.
Notice the last sentence. The "valid origins" in the "access token" are part of the client configuration, which is set via the admin UI.

Related

Is there a way to add a authentication in wildfly file handler

I am using a WildFly(version - 19) to do file directory listing using below configuration.
<subsystem xmlns="urn:jboss:domain:undertow:10.0">
...
<host name="default-host" alias="localhost">
<location name="/SoftwareRepository" handler="SoftwareRepo"/>
</host>
...
<handlers>
<file name="SoftwareRepo" path = "<Path to Directory>" case-sensitive="false" directory-listing="true"/>
</handlers>
</subsystem>
This works fine for me and listing the file list for the respective configured path. B
Now, my worry is about authentication. The file directory listing is happening when I access the URL but without any authentication.
How to add any authentication mechanism to do this file handler?

URLs breaking in WildFly on static served web content

I was given a weird requirement of hosting small campaign websites with 5-6 pages written in Angular and some APIs these websites can interact with. Everything coming from a WildFly instance.
I configured the paths and handlers using WildFly/Jboss' Undertow subsystem for each of these campaign portals. Their home page shows up when tried to access the the server with the path. Here's the example:
<subsystem xmlns="urn:jboss:domain:undertow:11.0" default-server="default-server" default-virtual-host="default-host" default-servlet-container="default" default-security-domain="other" statistics-enabled="${wildfly.undertow.statistics-enabled:${wildfly.statistics-enabled:false}}">
<buffer-cache name="default"/>
<server name="default-server">
<http-listener name="default" socket-binding="http" redirect-socket="https" enable-http2="true"/>
<https-listener name="https" socket-binding="https" security-realm="ApplicationRealm" enable-http2="true"/>
<host name="default-host" alias="localhost">
<location name="/app1" handler="app1"/>
<location name="/app2" handler="app2"/>
<filter-ref name="server-header"/>
<filter-ref name="x-powered-by-header"/>
</host>
</server>
<servlet-container name="default">
<jsp-config/>
<websockets/>
</servlet-container>
<handlers>
<file name="app1" path="${jboss.home.dir}/app1" directory-listing="true"/>
<file name="app2" path="${jboss.home.dir}/app2" directory-listing="true"/>
</handlers>
</subsystem>
However if I click any of the links inside the landing/index page within these apps, I get 404 - Not Found.
Ex: https://myhost.mydomain.com/app1 -> Gives the landing/index page.
Any link I click within that page, for instance, if there is 'faqs' and the URL is https://myhost.mydomain.com/app1/faqs, it resolves fine to that path but I am getting 404 - Not found.
Looking for a way to make this work.

Error starting application in .netcore

I'm getting the following error when navigating to my IIS published .netcore application:
I have set up my web.config file as so:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<!--
Configure your application settings in appsettings.json. Learn more at http://go.microsoft.com/fwlink/?LinkId=786380
-->
<system.webServer>
<handlers>
<add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModule" resourceType="Unspecified" />
</handlers>
<aspNetCore processPath="dotnet" arguments=".\KritnerWebsite.dll" stdoutLogEnabled="true" stdoutLogFile=".\logs\stdout" forwardWindowsAuthToken="false" />
</system.webServer>
</configuration>
Not sure if this warning is relevant or just outdated:
Severity Code Description Project File Line Source Suppression State
Warning The element 'system.webServer' has invalid child element 'aspNetCore'. List of possible elements expected: 'asp, caching, cgi, defaultDocument, directoryBrowse, globalModules, handlers, httpCompression, webSocket, httpErrors, httpLogging, httpProtocol, httpRedirect, httpTracing, isapiFilters, modules, applicationInitialization, odbcLogging, security, serverRuntime, serverSideInclude, staticContent, tracing, urlCompression, validation, management, rewrite'. KritnerWebsite D:\gitWorkspace\KritnerWebsite\src\KritnerWebsite\web.config 12 Build
The line in the web.config was as per the template, I just changed "false" to "true" for stdoutLogEnabled.
I have also created an empty folder in the root directory "logs" - I wasn't sure if this should get created automatically or not. Either way, nothing is being written to the logs, so I am not sure what to try next.
I have opened the solution in VS2015 on my host, compiled it and ran it successfully through commandline/localhost with dotnet run. This is running it in the production configuration, so pulling from my environment variables for insights key, and connection string. So I'm not sure why the site would run successfully on my host through dotnet run but not when published to IIS
How do I get further information on what the error is?
I'm not sure what exactly caused the logs to start correctly recording in ./logs... but they did. With the exception now being recorded I could see that my connection string I had set up in my Environment Variables was off.
Still not sure what caused the logs to not write out in order for me to determine this faster.
After updating my environment variable and running iisreset as per https://serverfault.com/questions/193609/make-iis-see-updated-environment-path-variable my website is now being served properly.

Allow loading of JSON files in Visual Studio Express 2013 for Web

I have the problem, that the IIS from Visual Studio Express 2013 for Web doesn't allow the loading of *.json files. When trying to load a *.json file I get a 403 Forbidden and a help page how to configure the IIS allow the loading of JSON files, but don't know what to do with this information / where the IIS is even located.
This is the error page:
HTTP Error 404.3 - Not Found The page you are requesting cannot be
served because of the extension configuration. If the page is a
script, add a handler. If the file should be downloaded, add a MIME
map.
Most likely causes: It is possible that a handler mapping is missing.
By default, the static file handler processes all content. The feature
you are trying to use may not be installed. The appropriate MIME map
is not enabled for the Web site or application. (Warning: Do not
create a MIME map for content that users should not download, such as
.ASPX pages or .config files.) If ASP.NET is not installed.
Things you can try: In system.webServer/handlers: Ensure that the
expected handler for the current page is mapped. Pay extra attention
to preconditions (for example, runtimeVersion, pipelineMode, bitness)
and compare them to the settings for your application pool. Pay extra
attention to typographical errors in the expected handler line. Please
verify that the feature you are trying to use is installed. Verify
that the MIME map is enabled or add the MIME map for the Web site
using the command-line tool appcmd.exe. To set a MIME type, run the
following command in the IIS Express install directory: appcmd set
config /section:staticContent
/+[fileExtension='string',mimeType='string'] The variable
fileExtension string is the file name extension and the variable
mimeType string is the file type description. For example, to add a
MIME map for a file which has the extension ".xyz": appcmd set config
/section:staticContent /+[fileExtension='.xyz',mimeType='text/plain']
Warning: Ensure that this MIME mapping is needed for your Web server
before adding it to the list. Configuration files such as .CONFIG or
dynamic scripting pages such as .ASP or .ASPX, should not be
downloaded directly and should always be processed through a handler.
Other files such as database files or those used to store
configuration, like .XML or .MDF, are sometimes used to store
configuration information. Determine if clients can download these
file types before enabling them. Install ASP.NET. Check the failed
request tracing logs for additional information about this error. For
more information, click here.
Detailed Error Information: Module StaticFileModule Notification
ExecuteRequestHandler Handler StaticFile Error Code 0x80070032
Requested URL http: //localhost:64107/Settings/Settings.json
Physical Path D:\GIT\RepoP_Paneon\Settings\Settings.json Logon
Method Anonymous Logon User Anonymous Request Tracing Directory
C:\Users\stefank\Documents\IISExpress\TraceLogFiles\REPOP_PANEON
More Information: This error occurs when the file extension of the
requested URL is for a MIME type that is not configured on the server.
You can add a MIME type for the file extension for files that are not
dynamic scripting pages, database, or configuration files. Process
those file types using a handler. You should not allows direct
downloads of dynamic scripting pages, database or configuration files.
View more information ยป
After some more googling, and experimenting I found out, that you have to define IIS settings in the Web.config.
After adding the following configuration:
<system.webServer>
<staticContent>
<mimeMap fileExtension=".json" mimeType="application/json" />
</staticContent>
</system.webServer>
it works like a charm.
Full setup file example:
<?xml version="1.0"?>
<configuration>
<system.web>
<compilation debug="true" targetFramework="4.0"/>
</system.web>
<system.webServer>
<staticContent>
<mimeMap fileExtension=".json" mimeType="application/json" />
</staticContent>
</system.webServer>
</configuration>
Better add remove tag in case future IIS has build in json support. This is my web.config section of mimeMap.
<system.webServer>
<staticContent>
<remove fileExtension=".woff" />
<remove fileExtension=".woff2" />
<remove fileExtension=".json" />
<mimeMap fileExtension=".woff" mimeType="application/x-font-woff" />
<mimeMap fileExtension=".woff2" mimeType="application/font-woff2" />
<mimeMap fileExtension=".json" mimeType="application/json" />
</staticContent>
<system.webServer>
Open CMD with administrator privilages.
Go to:
cd C:\Program Files\IIS Express
or
cd C:\Program Files (x86)\IIS Express
Run command:
appcmd set config /section:staticContent /+[fileExtension='JSON',mimeType='application/x-javascript']
We may need to distinguish the Visual Studio development environment (with IIS Express) from local IIS and a remote server (like Azure WebSites). To specifically target IIS Express, for example, we edit %USERPROFILE%\Documents\IISExpress\config\applicationhost.config under system.webServer/staticContent:
<mimeMap fileExtension=".json" mimeType="application/javascript" />
I need to make this distinction because my local (intranet) IIS already has the JSON mime type defined. So when I deploy to Azure websites I use this transformation in Web.Release.config:
<system.webServer>
<staticContent>
<mimeMap fileExtension=".json" mimeType="application/javascript" xdt:Transform="Insert" />
</staticContent>
</system.webServer>

WiX not configuring IIS site correctly

I have an installer which configures 2 websites, one of which has some applications under the root site. The top level site is configured for Windows Authentication only, as below:
<iis:WebSite Id="WebSite"
Description="Application"
Directory="WEBSITE_INSTALLLOCATION"
AutoStart="yes"
ConfigureIfExists="yes"
StartOnInstall="yes">
<iis:WebAddress Id="AllUnassigned" Port="80" />
<iis:WebApplication Id="WebApplication"
Name="Console"
WebAppPool="WebAppPool"/>
<iis:WebDirProperties Id="WebProperties"
AnonymousAccess="no"
WindowsAuthentication="yes"
AuthenticationProviders="NTLM,Negotiate"/>
</iis:WebSite>
Other (optional) components in the installer then declare applications/virtual directories as follows:
<iis:WebVirtualDir Id="HelpWebSite" Alias="Help" Directory="ApexHelpDir" WebSite="WebSite">
<iis:WebApplication Id="HelpApp" Name="Help" WebAppPool="WebAppPool"/>
<iis:WebDirProperties Id="HelpProps" AnonymousAccess="yes" WindowsAuthentication="no"/>
</iis:WebVirtualDir>
The behaviour I'm seeing is what I'd expect 9/10 times, but intermittently the installer will install the "Website" site with both anonymous authentication and windows authentication, rather than just the Help application with anonymous authentication. The only explanation for this that I can think of is that the act of adding a virtual directory/application underneath a root site occasionally causes the root to inherit the child authentication settings as well as its own.
Note: I tried to raise this as a bug on the wixtoolset.org site, but kept getting an error when trying to do so.
Alternatively, you can write a batch script to create a website and call from WIX as custom action.
Batch file
%systemroot%\system32\inetsrv\appcmd.exe add site /name:YourWebSite /PhysicalPath:%systemdrive%\inetpub\wwwroot /bindings:http/*:80:
WIX(product.wxs)
<CustomAction Id="CreateWebsite" Execute="deferred" Impersonate="no" Return="check" Directory="TARGETDIR" PatchUninstall="no" ExeCommand="Batchfilepath" />
<InstallExecuteSequence>
<Custom Action="CreateWebsite" Before="InstallFinalize">NOT Installed AND NOT PATCH</Custom>
</InstallExecuteSequence>
Change your ExeCommand attribute value to point to the correct batch file path.
The workaround for me was to disable Anonymous Authentication at the server level.
It seems that when this flakiness occurs it does inherit the setting from the server level, although I've no idea why it only happens sometimes.
Here's the Powershell script:
Set-WebConfigurationProperty -Filter "/system.webServer/security/authentication/anonymousAuthentication" -Name Enabled -Value False -PSPath IIS:\

Resources