OWIN OAuth Authorization Server and individual accounts - asp.net-mvc

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.

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

Call two distinct Azure AD protected APIs from Web App

Setup:
ASP.NET MVC5 application (Full Framework NET 4.7) with Azure AD on top
WebAPI (Full Framework NET 4.7) with Azure AD on top
.NET ADAL 3.x library (not MSAL) used in both apps
In the Web App, in Katana, the OWIN middleware:
i authenticate the user (org account in a directory i control)
i then exchange Authorization Code for Access Token (with resourceId: https://graph.microsoft.com)
i place the resulting Access Token in user claims
Now everything is fine and dandy, i can use the Access Token as Bearer and call Microsoft Graph and get /me user profile, picture and what not.
But how do i call my own Azure AD protected API from my Web App?
I can't just exchange the Authorization Code a second time for a different resourceId. I could context.AcquireTokenAsync() with app_id and app_secret, but the JWT i get back does not contain any user identifying claim, so now my API doesn't know anything about the calling user, it only knows that the confidential client (my Web App) did indeed present a valid token.
How do i request a token that will successfully call my API that will return some sort of user claims? The user principal name or user id is probably enough.
Should i just move all the Microsoft Graph calling logic to the WebAPI and exchange Authorization Code for my API's resourceId, or is there an in-place solution to my conundrum? What's the right pattern here? Ok not right, maybe just better.
You can request for a second access token with the same authorization code for another API.
Depending on how you request the access token, the audience of the token might be either the client id or Application ID URI of the API. So you must make sure that both are accepted audiences in the API.
In the case of ASP.NET Core APIs, you can add the following in JWT Bearer authentication config:
TokenValidationParameters = new TokenValidationParameters
{
ValidAudiences = new [] { "https://blabla", "g-u-i-d" }
}

CRM Web Api ADFS OAuth

We have an Azure hosted ‘on-premise’ instance of Dynamics 2016 running as an IFD utilising ADFS authentication. We now have a requirement for an Azure hosted API to communicate with the Dynamics instance using the CRM Web API. To achieve this we need to authenticate using OAuth authentication using ADAL as outlined here https://msdn.microsoft.com/en-gb/library/gg327838.aspx , utilising the Microsoft.IdentityModel.Clients.ActiveDirectory library. We have the following code to retrieve a token from ADFS
var resource = "https://reosurce.com/";
var clientId = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx";
var authProvider = "https://adfs.server.com/adfs/oauth2/token";
var redirectUri = "https://crm2Environment.com/";
var authContext = new AuthenticationContext(authProvider, false);
var authToken = authContext.AcquireTokenAsync(resource, clientId, new
Uri(redirectUri), new PlatformParameters(PromptBehavior.Always)).
Result.AccessToken;
The code example runs successfully, however is for use in an interactive flow situation and as soon as the AcquireTokenAsync method is called login dialog appears (makes sense as how else does ADFS know whether its ok to Authenticate), however this is obviously not going to work on the API which is domain agnostic and there is no way of passing credentials to ADFS (not that We would want to anyway). None of the alternative overloads to the AcquireTokenAsync method appear to be applicable to ADFS in the situation outlined (but open to suggestions). Are we missing something? Is there another way to retrieve the token with a non-interactive flow / without using Domain Account authentication? Bear in mind that the examples available for Azure AD do not appear to work in the ADFS scenario also we do not own or have access to the current ADSF server as this is managed by our infrastructure team (although if there is a requirement for them to make changes on the ADFS this is possible)
What version of ADFS are you using?
If ADFS 4.0 and the flow is server to server (sounds like it is) use client credentials which uses the knowledge of a secret key - no login / password.
Good link here.
Take a look at MSI (Managed Service Identity). This is a new communication protocol for Azure-to-Azure services.
Managed Service Identity (MSI) for Azure resources
As you research this, try not to fall into confusion with the old pattern (which is still valid for Service-to-AzureService communication) This is where you generate a ClientId/ClientSecret/Url on Azure that gives permissions, then share these values with the application that requires access. Here is an example of that Use Azure Key Vault from a Web Application The example demonstrates connecting to Azure Key Vault, but it could be any Azure service that uses Azure Active Directory Authentication.

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

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

Combining CAS with OAuth

We are already using CAS for single sign on for several web applications that we are hosting. Now we are going to deploy several HTTP/REST services in our network and those need authentication and authorization.
Would it be a good idea to combine CAS with OAuth ?
Users would still use CAS for SSO, but additionally login procedure would issue OAuth ticket that would be used to access REST services.
REST services can be protected via CAS proxy authn. Additionally, they can be integrated with OAuth. CAS provides both OAuth and OIDC protocol functionality as well.
That's certainly valid. OAuth 2.0 doesn't specify/dictate how the user (Resource Owner) is authenticated and CAS/SSO is fine for that. Effectively you'd be leveraging a CASified Authorization Server so that the Resource Owner authenticates with CAS to the Authorization Server, which is "just" an application to the CAS SSO system. The Authorization Server would then issue an access token down to the Client so that the Client can use that access token to access the protected resources i.e. the REST services.

Resources