Mixed Authentication in .net core API - .net-core

I'm building a multi tenant Service Fabric Application, that allows a tenant to specify a login type - Identity(asp.net)/Azure AD.
I have an Authentication service that checks to which tenant the user is linked to and then proceeds to check if the username:password for the user is valid, if valid it returns a JWT token to the gateway API/web API that then allows access to the rest of the services on the cluster.
This is further secured by roles to limit actions and data access etc.
Question 1
What would be a secure way to save the app id and secret given by that tenant if they use azure AD?
In my DB and encrypt the info, it would have to be decrypted to connect to the AD(Trying to keep in dynamic).
Question 2
I'm implementing my own sliding refresh tokens to obtain a new JWT after it expires, is there a better/standard approach?
Question 3
Is there a better/standard way to handle this multi-tenant sign in process.
Question 4
Is there a way to have optional claims set on the JWT Subject that would allow access to shared services but prevent access to tenant specific services if the claim value is incorrect?
Edit
Ideally the Roles should not be part of the tenants AD/B2C because they role are dynamic and managed from within the application.

Instead of building your own STS logic, have a look at IdentityServer, a popular and great OSS tool.
For example, have a look here for a multi-tenant example using asp.net core.
It supports adding custom claims to the token, by implementing a Profile Service. Services can be configured to use claims for authorization.
This blog post may also be useful.

I will very strongly advise you ride upon the Azure tenant model and let Azure AD manage all credentials and authentication. In today's world its a very bad idea to store and manage user credentials when there are plenty of Identity Providers available.
Recommended reading:
How to build a multi-tenant app with Azure AD
How to secure a Web API with Azure AD.
Libraries like MSAL.NET will automatically manage token caches and refreshes.
Use roles and groups in Azure AD
Claims in tokens issued can be customized to some extent.
disclaimer: I work for Microsoft

Related

Azure AD SSO for independent App Registrations

I need to provide an SSO between two independent applications via the Azure AD SSO.
My app (A) use Firebase as the backend and currently isn't registered in Azure AD.
The second App (B) is registered in Azure AD via App Registration and I think has password-based login now (but it doesn't really matter). Can't say what technology it uses for the backend.
I've read a lot of Azure documentation but can't understand how exactly should I connect them with SSO.
I see that I can connect applications from the Enterprise Applications list. Is this the only way to do it? In this case, I need to publish my app to the Enterprise Applications gallery but it feels like an overcomplicated solution.
SSO feature and experience depends on the type of auth-protocol being used. It also varies based on that. Lets say, your app uses OpenIDConnect then the SSO experience would be something like what mentioned here: https://learn.microsoft.com/en-us/azure/active-directory/manage-apps/configure-oidc-single-sign-on
If it uses SAML as the auth-protocol it looks something similar to: https://learn.microsoft.com/en-us/azure/active-directory/manage-apps/configure-saml-single-sign-on
and if its using Password-based SSO then: https://learn.microsoft.com/en-us/azure/active-directory/manage-apps/configure-password-single-sign-on-non-gallery-applications
Specifically for Password-Based SSO, it provides SSO by storing the credentials in the browser extension. With password-based sign-on, users sign on to the application with a username and password the first time they access it. After the first sign-on, Azure AD supplies the username and password to the application.
Password-based single sign-on uses the existing authentication process provided by the application. When you enable password single sign-on for an application, Azure AD collects and securely stores user names and passwords for the application.
Choose password-based single sign-on when:
An application doesn't support SAML single sign-on protocol.
An application authenticates with a username and password instead of access tokens and headers.
In your case, both you apps (MyApp-A and MyApp-B) needs to be registered in AAD and they should support neither SAML or OIDC.

Azure AD Securing API - GetAccessTokenForUserAsync not include claims roles

I have a web site that calls an API. To call the API from the web site I'm getting first a jwt token using GetAccessTokenForUserAsync(scope).
My problem is that this method doesn't retrieve user's roles inside the jwt token.
My user.identity.claims has a few roles but they are not include in the jwt token.
What I'm missing?
I'm to trying to including the roles in the jwt token because I need to secure my api methods. For example, a method can be called only by AdminMember, other method only can be called by SpecialMember.
Is there another way to secure my api without sending my user's roles?
Thanks
Since the roles are defined in your client app's registration, they will only be available in its tokens.
So, there are fundamentally two options:
Define the same roles in the API app registration as well. You will need to assign the roles on that app as well to the users. This could be made easier by using groups for the role assignments.
Change the API to use the same app registration. Now you will get the roles in the access token. Using one app registration can mean violating least privilege since then any permission you want to give to either the API or client app will be given to the other as well.
Depending on your case, you can choose either option :)

How to implement Role based access control in API using WSO2 stack

We are using WSO2IS as IAM server , roles and Users are managed in WSO2IS. WSO2EI WILL be integration server , exposing private APIs
What would be the right way to implement role based access control using , like some set of APIs only to be accessed by users with specific groups. How can I implement this most simplest way ? Is there a requirement of WSO2AM here ?
Thanks
EI is not the ideal way to exposing private oauth secured APIs. Even though you can achieve it with EI, that would be an excessive effort when integrating.
Use API Manager to expose the APIs to your crowd. Configure Identity Server as the Key Manager (Token Manager) of the APIM server. APIM server knows how to talk to the Identity Server to generate and validate access tokens. So there's no explicit effort to integrate the resource server(APIM Gateway) with the authorization server(IAM).
Share the user store between both the servers. (IS and APIM)
Configure IS as the Key Manager of the API server.
Register your API in the publisher/developer portal.
When publishing, you can define role based access restrictions to your API resources from the Publisher portal. (Roe : Scope mapping)
Once you define, IS will always check your roles upon providing an access token for you.
As you've already defined a role : scope mapping, scopes you request in your token generation request, will only be accepted if you (requester) has the expected roles. Therefore, the scope of your token will only be as good as the roles you've got assigned to yourself. Now, as the API resources you've published require a defined set of scopes, not all the access tokens will be accepted when trying to access the APIs. Only the ones with the expected scopes.
Configure IS-KM with APIM
Role based scopes

Validate username/password against Azure AD without a UI?

How can I validate a username/password against Azure AD without showing a UI? I have an autonomous processes running (think Windows Service or scheduled task) where the username and password are stored in a configuration table.
Since there is no "user at the wheel" so to speak, we can't use the normal method that shows the Azure login page (https://login.microsoftonline.com/{tenantId}).
1. Just make it work, no changes approach (Not Recommended)
You can try to get a token using Resource Owner Password Credentials Grant. (ROPC might be the least secure among all the different grants supported and brings potential attack risks. Also note that ROPC doesn't work with MFA and has issues with federated authentication users or may not work in those cases at all)
I don't think there is any method/endpoint available to specifically validate the username/password, but the workaround is if either username or password is incorrect, you will get an exception from the token endpoint when using ROPC, otherwise you get back a valid token which means credentials are good.
You can read about how to get a token using ROPC here:
Resource Owner Password Credentials Grant in Azure AD OAuth
2. Suggested Approach, some changes required (Recommended)
This might feel a little inconvenient at beginning, but it will be well worth the effort from a security standpoint. Note that this approach as well as the first one will meet your requirement of not going through normal login page as well.
Since there is no "user at the wheel" so to speak, we can't use the
normal method that shows the Azure login page
(https://login.microsoftonline.com/{tenantId}).
As you mention that the autonomous process is like a Windows Service or Scheduled task, from Azure AD and OAuth 2.0 perspective your process looks like a Daemon service. So instead of using a username/password credentials directly from configuration, which violates security best practices, you should be looking at using Client Credentials Grant. It's strongly advised NOT to collect/manage/store end user credentials (or create old world Service Accounts) directly in your applications.
You can read about it in detail here: OAuth 2.0 Client Credentials Grant with Azure AD.
Also visit this documentation for all Azure AD app types and scenarios, specifically those listed for Daemon apps. Link
To put it very briefly, your process gets represented by a registered application in Azure AD and for credentials part you can use:
a. Client ID + Client Secret Key (provided by Azure AD specifically for your application. you can generate more than one secret keys for different purposes with different expiration etc.). Sample C# code with Client Secret
b. Client ID + Certificate (pass a JWT that you need to create and sign with the certificate you registered as credentials for your application). Sample C# code with Certificate

Authorization method for REST API utilising Active Directory

What is the best method of securing a REST Web API with the following requirements. The system has an Angular JS frontend with the REST APIs implemented in ASP.net.
There are two "roles" in the system, users will have one of the
roles. One role should allows access to some APIs (call it "VIEW"),
the other role allows access to other APIs
All users are in Active Directory, so if I have a username, I can check what role they are in- Some clients are on Windows boxes, the others are on Linux
I would like to persist the session so I don't have to look up AD for every API call
I would like single sign on. On the Windows machines, I don't require them to enter user and pass as I already can retrieve their username using Windows Authentication.
I believe that Oauth would be my best option.
There are two "roles" in the system, users will have one of the roles.
One role should allows access to some APIs (call it "VIEW"), the other
role allows access to other APIs
For role based authentication, you can use [Authorize("Role" = "Manager")]. The token will be provided by the identity server and will contain the claim as Role.
All users are in Active Directory, so if I have a username, I can
check what role they are in- Some clients are on Windows boxes, the
others are on Linux
If you have ADFS then you can have an Identity server that trusts the ADFS. The ADFS will provide a token which will have the claim for role and your Identity Server will do the claims transformation and will return the same Role claim back to angular app.
I would like to persist the session so I don't have to look up AD for
every API call
For this while requesting the token, you can ask for offline scope so the Identity server will provide the Refresh Token with Access Token so you don't need to ask for AD again and again.
I would like single sign on. On the Windows machines, I don't require
them to enter user and pass as I already can retrieve their username
using Windows Authentication.
For this one, you can have your Identity sever trust the WSFederation for windows Authentication.
So basically you need to setup Identity server that will provide you with the token and the REST API will use that token to verify claims to return the correct information back to the user.
I am not sure what you expect exactly. Anyway, first I'm gonna reformulate your question with requirements:
you accounts and role are in active directory
you want to manage roles based on an active directory group
you want anybody whatever the system (windows, linux, mac, mobile...) to connect on your application using the same authentication
you want to avoid your AD to be hit constantly (not at any call for example)
if the user is connected on an application that uses the authentication system, he doesn't have to do it so again on another application that uses the same authentication system
If these requirements are yours. I believe the only standard (and clean) solution is to use OAuth. I'm not gonna go in detailed description of OAuth, but this authentication protocol is the most standard one on the net (facebook, google, twitter...). Of course as you don't want to use facebook, google or twitter accounts in your business applications but your active directory accounts you'll have to install/setup/develop your OAuth identity provider using accounts of your active active directory server. Your choice will depend on how well you know ADFS protocol and its different flows (code, implicit, assersion) You have two solutions for it:
Use ADFS: install ADFS; it provides a OAuth portal that will work out of the box with asp.net mvc. This uses the code flow of OAuth that is the only OAuth flow supported by ADFS. For roles and its related AD groups, you'll have to map role claims with AD groups. (it's in the setup of adfs, you'll find many tutos on the net). You'll find lot of tutos as well about how to use ADFS with asp.net mvc/asp.net webapi. I mention .net here, but every technology has an implementation for OAuth authentication (nodeJs/express, php, java...).
Use thinktecture identity server (.net technology). This will provide all the foundation to implement a custom identity server with the least effort: http://www.thinktecture.com/identityserver / https://github.com/IdentityServer/IdentityServer3. It contains an addin to plug its accounts to active directory. With this, you can use implicit and assertion flows.
Use oauth2orize (for nodeJs): https://www.npmjs.com/package/oauth2orize. This will permit you to make the same than thinktecture identity server but in nodeJs. Apparently you'll have to make all the wirering with ad manually. With this, you can use implicit flows (not sure about assertion flows).
At application side, most of frameworks can authenticate easily using OAuth with a lot of existing frameworks. For example, even if you make a single page application, you can use adal.js or oidc.js for angular if you use angular. As I mentioned above, all this is taken in charge by asp.net mvc/webapi out of the box but I know it's the case for other server technologies. If you have more questions, don't hesitate as I'm not sure of what you expect exactly.

Resources