How do I integrate an existing asp.net MVC application with IdentityServer? - asp.net-mvc

How do I integrate an existing asp.net MVC application with a separate IdentityServer application?
I have an existing asp.net MVC site using identity 2.0 for authentication.
I now have a second application running asp.net Core 1.1 which serves API's which talk to a client (mobile) application.
I need to share authentication across all 3 applications.
From what I've read, I need to add SSO, and IdentityServer seems like a great solution for this. I plan to set up IdentityServer as a 4th application and connect it to the new .net API application and client application.
But I can't find any example for how to have my existing Asp.net application use the new identity server for authentication.

You will have 4 applications are you stated.
The IdentityServer4 application for identity and access control. This will be the SSO service and the STS (security token service)- the authority. As of today you will build this in ASP.NET core 1.1. To be an SSO you will of course need to have a user database; using ASP.NET Identity works well and integrates nicely with IdentityServer.
Your Web API, which you say is running ASP.NET Core 1.1. This, in OAuth terms, is called an API Resource. You could sub divide this API into separately securable sections called API Scopes.
The existing MVC web application with your current user database in ASP.NET Identity. This will be a Client of the IdentityServer authority (#1 above). You could use the Authorization Code Flow (more secure) or opt for Implicit or Hybrid flow. An example of how to setup an ASP.NET MVC web application as a Client of an IdentityServer instance can be found in their official documentation: http://docs.identityserver.io/en/latest/quickstarts/3_interactive_login.html#creating-an-mvc-client.
Essentially, you
(a) register the client with IdentityServer, then
(b) add some startup code in the client app that will tell it to use IdentityServer for authentication- something like this...
app.UseOpenIdConnectAuthentication(new OpenIdConnectOptions
{
AuthenticationScheme = "oidc",
SignInScheme = "Cookies",
Authority = "http://localhost:5000",
RequireHttpsMetadata = false,
ClientId = "mvc",
SaveTokens = true
});
You could at that point use both the internal user database for logging in as well as the external IdentityServer- that is, you could log in to the MVC web app two different ways. The IdentityServer app could be considered an "external provider" to your MVC web app.
Are you going to migrate your existing usernames and passwords (and roles, etc.) to the new IdentityServer instance/database? This answer will have to be "yes" to achieve SSO and shared identities and access controls across applications.
SSO is only possible if the user logs in with the IdentityServer app. Though, you probably won't actually achieve SSO since they are using a browser on a desktop machine and a mobile app on a phone- not really able to share cookies or tokens across devices.
The mobile client. This would be another Client like the MVC web app except using the Implicit Flow for sure. Again, register the client, and then code the app.

You build your Authentication application by using IdentityServer4. Treat each of your application as an identityServer4 client and API as ApiResources, so they all will have unique clientid, callback uri etc. You need to add IdentityServerAuthenticationOptions to API, and OpenIdConnectOptions to mvc application.
For example, an WebAPI startup.cs may have:
public void Configure(IApplicationBuilder app, ILoggerFactory loggerFactory)
{
loggerFactory.AddConsole(Configuration.GetSection("Logging"));
loggerFactory.AddDebug();
app.UseIdentityServerAuthentication(new IdentityServerAuthenticationOptions
{
Authority = "http://localhost:5000",
RequireHttpsMetadata = false,
ApiName = "api1"
});
app.UseMvc();
}
Anyway, First you need to understand how IdentityServer works. And then you need to build the identityserver app what will access to your users context. You will achieve share authentication across three app by allowing same api scope.
And this is the best place to start

Related

Authentication with JWT: Securing Views from the consuming client perspective

I have created a Web API using ASP.NET Core 2.1 and it uses (successfully) JWT as a method of authorising requests.
The API is linked to a SQL Server database.
My users are stored in it using Identity as the base framework.
To authorise access for my API I take the username and password which is checked against the stored (Identity based) user.
Successful login returns an Access Token (with a 30min life).
Upon first logging in, a Refresh Token is generated and stored against the Identity user and sent back from the API.
All of this works well. My next step was to create a separate .NET Core 2.1 MVC site which consumes the API.
My question is:
From the MVC site point of view, how do I secure my controllers and views based on this security set up? I would normally use the [Authorize] attribute as part of Identity.
All I have on the MVC site side at the moment is the Access Token (and Refresh token) for the user in question.
I'm thinking the following solution:
MVC Site has it's own database and authentication for users (using Identity).
The connection (credentials/tokens) to the API is stored separately in the MVC site database and used as a 'global' way on the server-side to execute calls against the API
You should use an OpenID Connect and OAuth 2.0 framework. please check IdentityServer4. It also support asp.net core identity
IdentityServer is an OpenID Connect provider - it implements the
OpenID Connect and OAuth 2.0 protocols.
Different literature uses different terms for the same role - you
probably also find security token service, identity provider,
authorization server, IP-STS and more.
But they are in a nutshell all the same: a piece of software that
issues security tokens to clients.
IdentityServer has a number of jobs and features - including:
protect your resources
authenticate users using a local account store or via an external identity provider
provide session management and single sign-on
manage and authenticate clients
issue identity and access tokens to clients
validate tokens

MVC multitenant application with different authentications per tenant

I've been searching for many hours about a viable architecture for my scenario.
We would like to have a multitenant MVC application where each tenant belongs to a different company.
Each tenant have settings where we can configure their authentication type : Customer AD or Forms.
Is it possible to allow each company to login using their own active directory ? Or by default if they don't have AD, we use forms authentication.
I've read some articles about Azure AD, AD Federation Services + WIF (or more recently OWIN), but I would like some guidance about solutions to achieve it.
Thanks
This is a pretty standard scenario in Azure AD. You'll want to register an Azure AD app in the Azure portal, and use the OWIN OpenIdConnect middleware to do login/session management. If you want to also call a web API or the Microsoft Graph, you may also need to include ADAL (Active Directory Auth Library) to help exchange auth codes for tokens.
Here's a great code sample that shows you how to build a .NET multitenant MVC App. Moreover, the rest of the docs for this stuff can be found at the Azure AD developer page.
Having done this before, the way I did it was to use asp.net-identity and per tenant override the SignIn Manager via dependence injection.
The sign in manager is where the authentication takes place, so there isn't a drop-in framework that just does it (I am aware of), but just overriding a couple of methods in a single class is pretty easy.
Have you looked into Azure AD B2C? You can have users sign in with their companies emails/ AD.
Take a look here: https://azure.microsoft.com/en-us/services/active-directory-b2c/?cdn=disable
As per other answers, Azure AD allows multi-tenancy. Literally just selecting a check-box in the config.
However, the standard way of authentication is OpenID Connect / OAuth.
Also, you cannot change the mode of authentication.
You mention ADFS and on-premises AD. Where do these fit in?
Using ASP.NET Identity along with OpenID connect, you get this functionality. ASP.NET Identity has local accounts, and with OpenID Connect to Azure AD you can have users sign in with their Azure AD account.
The application definition needs to be a multi-tenant application.
You can pretty much follow the instructions here if you are using ASP.NET Core, and then add OpenID Connect as described e.g. here or by just adding code similar to this after the app.UseIdentity calls:
// Add Authentication services.
services.AddAuthentication()
// Configure the OWIN pipeline to use OpenID Connect auth.
.AddOpenIdConnect(option =>
{
option.ClientId = Configuration["AzureAD:ClientId"];
option.Authority = String.Format(Configuration["AzureAd:AadInstance"], Configuration["AzureAd:Tenant"]);
option.SignedOutRedirectUri = Configuration["AzureAd:PostLogoutRedirectUri"];
option.Events = new OpenIdConnectEvents
{
OnRemoteFailure = OnAuthenticationFailed,
};
});
If you create a new app with Individual User Accounts, you can add the code above after the boilerplate code for Identity in the ConfigureServices method of Startup.cs, and then you are pretty much good to go.

Identity Server 3 with Single Sign On

I currently have a solution with three projects
Identity Server 3 with web host
MVC Application with UseOpenIdConnectAuthentication
Asp.Net Web Form Application with UseOpenIdConnectAuthentication
Both the Mvc and WebForm are pointing to the same Identity Server and both are configured to use the same client. The Client is setup as a Hybrid flow and has both the MVC and Web Form urls registered against the client.
Both can authentication with the same user account details and the claims identity is working fine within the applications. Both are setup using the OpenID Connect Authentication with the same
Client ID
Authority URL
Response Type
Scopes
SigninAsAuthenicationType (Cookies)
Both the Mvc and Web Form are set up as UseCookieAuthenicationType (Cookies).
However when I transfer via a hyperlink from the WebForm application to the MVC application, it does not recognise that I am already logged in.
Can anyone tell me what I have configured wrong?
Can you please provide some code snippets from clients UseCookieAuthenicationType/UseOpenIdConnectAuthentication -configurations? Is Authority -property setted with valid endpoint? With security cookie it is case sensitive - this is important

OWIN OAuth Authorization Server and individual accounts

I have an application that has been under developpment for quite a while now.
We used OWIN with individual accounts.
The application is asp.Net MVC with WebApi and AngularJs frontend.
The API grew quite a lot and we have cases where we need to give access to clients to the API directly.
Problem is that it is secured using CookieAuthentication.
I would like to use the OAuth that is packaged with OWIN and directly available (though a lot of the implementation is up to the developer as it looks like).
Is it possible to add implementation of the Authorization server (http://www.asp.net/aspnet/overview/owin-and-katana/owin-oauth-20-authorization-server) in the same application or should I deploy another server?
The whole thing is that nothing should change for the users of the web site that is currently deployed, this is just an extra feature to help API security.
Thanks
Yes it's possible to implement your Authorization Server to grant client access to your API.
OAuthOptions = new OAuthAuthorizationServerOptions
{
TokenEndpointPath = new PathString("/OAuth/Token"),
AuthorizeEndpointPath = new PathString("/Api/Account/ExternalLogin"),
Provider = new MyOAuthAuthorizationServerProvider()
};
I leave the implementation of the OAuthAuthorizationServerProvider to you but you can find some inspiration with the Thinktecture Identity project.
Last step is to register your new middleware:
// Enable the application to use bearer tokens to authenticate users (Authorization Server and Resource Server)
app.UseOAuthBearerTokens(OAuthOptions);
You can then send requests to your API with the access token you received from your OAuth provider using the 'client_credentials' grant type.
Hope it helped.

Username and password authentication for WIF (Windows Identity Foundation) in ASP.NET MVC

We have two existing legacy web applications, one for the intranet using windows authentication within the domain, and one internet application, performing a custom web forms username + password based authentication. Now a new web applications is developed and will be available in the internet to both internet and intranet users, handling both authentication models. Therefore we decided to use WIF. We're going for ASP.NET 4.5 MVC 4 on Windows Server 2012.
The intranet authentication shouldn't be a problem as we can use ADFS 2.0 here.
But we currently have no clue how to solve the username + password authentication. It looks like we need to develop a custom UserNameSecurityTokenHandler to authenticate users which provide username + password information which is verified against our custom membership provider. But I need some assistance with the whole workflow...
Assume that we have a custom login page for internet users; and assume that we managed to route internet users to this login page (in ASP.NET MVC), what's the missing part from here to a valid token? How would the form or the MVC controller action which received the provided username + password proceed to trigger the configured WIF identity provider?
The most elegant solution would be to create another STS for the external users and have ADFS trust this as an identity provider:
External users will be redirected to the IdP STS that would use the usr/pwd database. Internal users will authenticate through ADFS directly (against AD).
In this scenario, ADFS is acting both as an IdP and a Federation Provider.
For this to work you need both ADFS and the IdP (and the app) exposed to the internet. An STS you can use that leverages membership is IdentityServer, which is open source and you can of course customize for your needs.
With this architecture you don't need any special customizations/extensions in the app. You will need to handle "home realm discovery" though. Which is the process of knowing where to authenticate users on (e.g. intranet vs. extranet). Presumably, you might have different URLs, etc.

Resources