IdentityServer4 Restart causes 401 unauthorized until API app pool is reset due to metadata - identityserver4

We have an IdentityServer4 Host as our IDP. We have a 4.6 WEB (SPA) calling an API using Hybrid flow (Calling the API by passing the accessToken). Everything is working as expected. Please note that on the API we are using IdentityServer3.AccessTokenValidation package to authenticate with IdentityServer4.
Scenario
Restarting Identity Server 4 Host causes newly logged do users a 401 unauthorized call to the API. We know of 2 solutions how to solve this issue:
1.) Restart the API App Pool (undesired)
2.) In the API, setup of app.UseIdentityServerBearerTokenAuthentication to set AutomaticRefreshInterval to 5 minutes of caching. After 5 minutes, newly logged on users can now retrieve data from the API.
The question is:
1.) Is there another option we can do beside what is mentioned above?
2.) If we do set the AutomaticRefreshInterval to the lowest possible cache value of 5 minutes, can you foresee any potential issues that we should account for? e.g. performance issues, security concerns, etc?

If using a temporary in-memory signing key then you'll get this behaviour. You need to create a persisted signing credential like an X509 certificate and load it when your IDS4 service starts.
Some guidance here: http://docs.identityserver.io/en/release/topics/startup.html#refstartupkeymaterial
See my answer here for a code sample on how to load a cert or certs from the machine certificate store:
How we can replace AddDeveloperSigningCredential on AWS Serverless Lambda environment?

Related

How do you configure a Blazor Server application using Azure AD in a load balanced environment?

I have an intranet Blazor Server application created using the Visual Studio template with the Work or School Accounts authentication option. Everything was working beautifully when running on my local machine and when the app was published to our development environment. However, once I moved the app to our staging environment, the application would sometimes crash after authenticating the user in Azure.
After troubleshooting the issue, I believe the problem to be that our on-premises staging environment is load balanced (mimicking production). Our dev environment is not load balanced. I think what was occurring was that once authenticated in Azure and redirected back to the application, the user doesn't always land on the same server due to the load balancer. This breaks the Signal-R circuit and caused the application to crash. This also explains why the error was random; happening maybe 2 out of every 10 logon attempts. To test this, I removed Azure AD authentication from the application and allowed anonymous access to every page. The crashes stopped.
My question is if anyone knows of any workaround to get Blazor Server with Azure AD authentication working with an on-premises load balancer. I searched all over the web and the only workaround I found was to use sticky sessions with Azure Signal R service. We are not hosting apps on the cloud yet. Is switching to Blazor Webassembly the only option if I want to use Blazor with authentication in my environment? Someone at work suggested switching the application to use our on premises ADFS server. However, wouldn't that encounter the same issue?
For reference, here is the code in startup.cs ConfigureServices method that sets up the Azure authentication in the application:
services.AddAuthentication(AzureADDefaults.AuthenticationScheme)
.AddAzureAD(options => Configuration.Bind("AzureAd", options));
services.AddControllersWithViews(options =>
{
var policy = new AuthorizationPolicyBuilder().RequireAuthenticatedUser().Build();
options.Filters.Add(new AuthorizeFilter(policy));
});
I found the solution to this and am posting it here in case anyone else is facing a similar issue.
It turns out the problem wasn't SignalR or anything specific to Blazor Server. After enabling the developer exception page on the load balanced environment, I saw that the error was "Unable to unprotect the message.State". The application state is encrypted by middleware before the user is authenticated by Azure AD. When Azure AD posts back, it includes that encrypted state which is then in turn decrypted on the client side by the middleware.
The key needed to decrypt is by stored on the web server. When in a load balanced environment, if you land on a different server than where you started, the middleware will then be attempting to decrypt state with the wrong key. This of course results in an error.
To fix this you have to store the keys on a central location like a file share instead of on the server itself. Implementing the fix is actually simple. Include the following line in ConfigureServices in startup.cs:
services.AddDataProtection()
.PersistKeysToFileSystem(new DirectoryInfo(#"\\server\share\directory\"));
There are also options to store keys on Azure if that is preferred.
This post by Kevin Dockx is what finally gave me the answer:
Solving Correlation Failed: State Property Not Found Errors (OpenID Connect Middleware / ASP.NET Core)

Identity Server 4 with WebAuthN - using GrantType (FIDO 2.0)

I'm using Identity Server 4 to authenticate users with WebAuthN (https://w3c.github.io/webauthn/).
I have multiple clients that that hit an api client. My api client is responsible for deciding which auth provider to use, passing data (server to server, server to external api) and orchestrating the auth process.
One auth provider we are using that we own is identity server 4 and this is where we are implementing WebAuthN.
I'm not sure which is the recommended way to implement this in Identity Server 4. I'm down to 2 options
Create an API endpoint on identity server to authenticate to users credential
Create an extension grant type and call the TokenEndpoint API using the new grant type (my extension grant type would be a mix of the built in Hybrid grant type followed by the WebAuthN code).
Are both ways valid from a security standpoint (not opening up a hole) and fit with ID4 or is there another way?
I've recently done some work on implementing this, but for second-factor only at this point.
Long story short, it needs to run in the context of the end user's browser (given that it's a JavaScript API) so really it needs to be built into the sign in flow via the authorize endpoint.
For example (assuming no local client or IDP sessions already exist):
User visits client application
Client redirects to authorize endpoint
Authorize endpoint redirects to interactive authentication UI which then decides what method to use
Do the WebAuthn challenge, validate the result and establish a session cookie
Redirect back to authorize endpoint
Issue tokens and redirect back to client
You'll also need to provide a way for users to register their authenticators. The resulting credentials are tied to the site origin so this must be done within your identityserver4 implementation - the same application that will be doing the challenging.

Identity Server and Active Driectory

My current setup is a fairly simple one. I am running Identity Server 3 which is used to provide oauth access tokens which can be used against and a number of our web api endpoints. The identity server has custom user service which authenticates requests against a custom user table in our sql database.
We have a new 3rd party software provider, this provider requires that our users (staff in our call centre) logon to their application via a proprietary login, not against our existing user accounts. We have built an api for this 3rd party which they required for their integration, as with the rest of our api's this is secured using oauth bearer tokens via identity server.
Our staff are all locally logged on to an active directory domain. Is it possible to configure identity server to issues auth tokens for a user who is already authenticated against active directory? I like to achieve this without prompting the user for their credentials again.
I've read around and at this point I'm very lost as to the correct approach, some form of federation seems appropriate, but I couldn’t find a reasonable introduction / walkthrough to help me get started.
What is an appropriate approach and are they any relatively easy to consume primers on the subject?
Yes, you should be able to make it work. The samples contain a windows auth provider. Using this, your identity server would authenticate people in without prompting for a password. Once authenticated, it would then issue tokens same as any other auth. You may need to a bit of experimenting to get it working, but from what you've said it should work in your situation.

API authentication with ADFS and Angular.js

I'm tried to build a new rich application and i'm having some problems designing the authentication process.
I've only two requirements :
An API needs to be available
An ADFS needs to be used to authentication
My first thoughts was to build the API and to use Angular.js for the frontend. However, I can't see how the authentication should work.
My API needs to be available though scripts. As far as I saw, the ADFS authentication always display t the webpage for the authentication process.
API are usually secured with OAuth2. We used an client id and a client secret to generate a token. But I can't have this behavior with an ADFS.
The only solution I see is to provide two authentications behavior with my application. One with the ADFS for the web access and in the web interface, add a possibility to generate a client id and a client secret associated with an user account that could be used for the API to the headless authentication.
Someone has already faced this kind of scenario?
Thanks a lot!
I assume the 'ADFS needs to be used for authentication' really means 'users should be able to use their Active Directory domain credentials to authenticate'.
If that is the case, you should take a look at Thinktecture IdentityServer. It's an OAuth2 authorization server that you can use with a Active Directory identity provider.
P.S. ADFS 3.0 that comes with Windows 2012R2 only supports the authorization code grant, which is not suitable for JavaScript apps.

How to accomplish google oauth authentication using nancy api and angularjs?

I have been looking around for this issue and haven't found anything yet.
I want to create a webapp that requests offline access to google api, and the my main concern is that I'm using angular as a front-end and I'm consuming a api created in nancy.
I have been able to get access but only for a couple of hours, but I need the user to grand offline access to the app because it's going to have a task running every amount of time needed.
Have anyone already accomplish this one? Tried? Experience? I've tried to call the google oauth api to request the token but it returns 405 method not allowed.
You can use Simpleauthentication, which has Nancy specific NuGet package. Just follow the instruction to set ip SimpleAuthentication in a Nancy app.
I've never used nancy. But in general, your OAUTH concerns should be handled server-side. The user validates against the google oauth, that google oauth flow returns to the back-end server, and the back-end server gives up a key, cookie, or something like that, which your front-end now uses in its request.
That's at least how I handle it. I use a token-based scheme for all my $http requests from my back-end API, which returns 401 if there's no valid token on the request and 403 if there is a token, but that token doesn't authorize that resource. I stuck a httpProvider interceptor in angular that, in the event of a 401, initiates client-side login flow.
Specifically, the token just is a randomly generated series of bits turned into hexadecimal, and then I stash it in redis as a key whose value is the user_id associated with this login.
Of course all of this requires a real https stack to be secure, since I'm just pushing what amount to plain-text one-time keys around, but that's about all you can do about that.

Resources