Create GraphClient with UsernamePasswordProvider with client secret - azure-active-directory

I created a desktop application that talks to Graph API (Beta).
In the development version, I deployed it on the application I created myself on Azure AD. As one of the requirements is not to show login dialog when using the application, I decided to go with UsernamePasswordProvider, which I provide the user name and password of my account and everything works fine (I didn't put client secret in my application).
When I'm about to deploy it on customer's network, I asked the admin and he provides me the service user name, password, tenant ID, client ID, and a client secret.
I tried using Postman to check if I can get an access token from those info and I can only if I provide the client secret along with user name and password.
When I'm back to the code, UsernamePasswordProvider's constructor accepts IPublicClientApplication which has no option to create the application with client secret.
I understand that there is a reason behind as the secret can be easily stolen if the application got decompiled but, if I'm (in fact, my client) not serious about this, is there any way to initialize the GraphClient by putting user name, password, and client secret together for authentication?

Important, the Username / Password flow is not recommended because your application asking a user for their password is not secure. For more information about this problem, see this article.
If you still would like to use it, you could put username and password of that user in Key Vault and fetch those in your code.
string keyVaultName = Environment.GetEnvironmentVariable("KEY_VAULT_NAME");
var kvUri = "https://" + keyVaultName + ".vault.azure.net";
var client = new SecretClient(new Uri(kvUri), new DefaultAzureCredential());
var secret = client.GetSecret(secretName); // get username or password here
I recommend you to use ClientCredentialsProvider, it enables service applications to run without user interaction.

Related

How should I store OAuth with my own authentication system?

I have an existing signup/login system: a user enters an email and password. The password is hashed. I store it in a database.
When a user logs in, they entire their email and password. The password is hashed, and I look up the email in the database and check that the email matches. If it does, they are logged in.
I want to add a system to let users login with a 3rd party OAuth, such as GitHub. I have that setup, but I am unsure what data to store in my database.
I was thinking I take their GitHub email as the email and then use the access token for their GitHub as the password (so I would hash it and store it.)
I think this would work, but I am worried that the access tokens could change meaning they would be locked out of their account.
If I shouldn't be using the access token as a password, what should I be using? I need to store the user's email on my database but that requires a password currently, which I can't get if they use GitHub login.
(Note that when the user logs in, I call my backend to generate an access token (JWT) which I can use to require their user details and then store it in local storage. I'd like to then be able to do the same thing with with GitHub or whatever.)
oAuth is usually for authorization. Meaning, you get an access token from the authorization server, the resource server validates it and let the user access to the data.
In your case, you "do not really need" the access token - you want to use oAuth just for the authentication. Web-applications (like StackOverflow) do this to "save the trouble" of handling the authentication flows. Meaning, if I write a secured application, I need to implement somehow the create account flow, login flow, forgot password, etc. When you use a 3rd-party authentication, you save this trouble.
However, your application does need some user-id to perform actions; so you must create a user-id in you app when a user appears for the first time. Since then, you do not need to worry about password-expiry, forgotten-password and even not for the login. When the user logs-in, you get the access token and all you need to do is to get yours app' user-id from it.
Thus, I do not see a reason why you need to store a 'password', or the access token.
Hope that makes sense.
What you are looking for is actually OpenID Connect - it's an authentication framework built on top of OAuth, which lets you log in users using external Identity Providers, like Github.
When a user logs in using GitHub then you will receive an id_token in a form of a signed JWT. You can easily verify the authenticity of the JWT - so you can easily make sure that the id token really comes from Github and presents real data. Usually one of the information in the id token will be the user's email. You can use that to look up the user in your database. You don't need any password in this case.
So, you will have two ways of finding a user in your DB - either through comparing the email and password, or by looking up the user's email from a validated id token from Github.

Azure AD Enterprise Application - Identify Caller Application

I have a REST API which uses Azure ADD App registration to allow other apps to call it.
In the Azure Portal, I have registered it as an Enterprise Application and also registered the consumer applications and assigned them Roles appropriately.
The authentication and RBAC works fine.
But the use case that I am working on requires me to identify and log the incoming request calling application's name (The one seen in the portal as 'Display Name', when we view the list of users and groups for an enterprise Application).
As advised in the internet, I am using some Identity related API to read the claims from the request header.
var provider = claimsUser.FindFirst("http://schemas.microsoft.com/identity/claims/identityprovider").Value;
var sid = claimsUser.FindFirst(ClaimTypes.NameIdentifier).Value;
OR
var sid = claimsUser.FindFirst("stable_sid").Value;
But this gives me a GUID value which I couldn't map to any of the consumers of the Enterprise Application.
The clients are all registered in the Azure portal.
In the Portal, I can see the apps in the "Users and Groups" section for the Enterprise application, with their appropriate roles.
In terms of usage, before making the call, the clients generate a bearer token based on the certificate that they get from Azure. The make the call with the bearer token attached to the request header. This bearer token is validated against the Azure AD, in the filters set before every controller..
What I want is to get are the details about this client who has made the call.. As per some repliers, and, to which I agree, the Guid that I get as part of the previous call mentioned above is for the actual user and not the app itself which is making the call.
Can anyone throw some light into it.. some code snippet will be of real help..
I'm not sure what authentication flow you are using, but SID is generally for a user that's logged in, not an application. if your client applications are using client id and secret, the token it returns that you send to the api should include the app registration guid. https://learn.microsoft.com/en-us/azure/active-directory/develop/v2-oauth2-client-creds-grant-flow#access-control-lists . So the appid and iss should give you the guid of the app registration. using this, you can make a call to graph api, to identify the display name of the app registration. https://learn.microsoft.com/en-us/graph/api/application-get?view=graph-rest-1.0&tabs=http
If your app is a user login app, and you don't want to make a call to graph, the other option you could do as a workaround would be to create app roles and assign users to them but name the app roles with some convention that includes the app's display name. then the name could come through under roles claim.. https://learn.microsoft.com/en-us/azure/active-directory/develop/howto-add-app-roles-in-azure-ad-apps
those are some options.. but other than calling graph or kinda working around to inject the name into a different claim of the token I'm not sure of any other method to get the "app registration's display name"

Azure Active Directory Web Application without login current user

I am following an older tutorial (https://code.msdn.microsoft.com/Write-Sample-App-for-79e55502) that shows how to create a web application that connects to an Azure Active Directory tenant using ADAL. There is a class library that contains DirectoryService classes that I believe does the work in retrieving AD user properties. I am wanting to create a login method for this project for security purposes, and to be able to identify what user is logged in to the application. Currently there is not a signin method that authenticates against AD by entering a username/password, so I am a little puzzled at how the app can retrieve user properties with just the AppId,Domain,and AppSecret in the Web.config without actually having someone login with either their AD creds or redirecting to login.microsoftonline/{tenantId}.....I do not know if I am making sense, but I want to be able to add a login method so a user is forced to login so it gets the claims for that specific user but if I am already using ADAL, can I also incorporate Owin?
There are two parts to your question -
1. How is this app working today, without asking end users to explicitly sign in
This sample is using Client Credential Grant, in which you don't need end users to sign in, but use the identity of an application itself to get the auth token and use it for further operations. As you mention yourself, it just needs AppId, Domain and App Secret from web.config. You can read all about it here - Client Credentials Grant
Related code to acquire token is available in MVCDirectoryGraphSample\Helpers\MVCGraphServiceHelper.cs file
AuthenticationContext authenticationContext = new AuthenticationContext(authString);
ClientCredential clientCred = new ClientCredential(ConfigurationManager.AppSettings["AppPrincipalId"],
2. How to add a login method to force users to sign in to your web application
You can start using something like Authorization Code Grant flow, instead of client credentials. Look here for documentation on different scenarios that Azure AD supports. Your case looks like a web application calling Graph API, described here
Exact code sample to do this is available here - Code Samples

Salesforce Docsign API Integration Account credentials

I am working on SalesForce-DocuSign Integration (eSignature Process). I have successfully connected to Docusign demo environment and tested the APIs & functionality is working as expected.
In my code username, password and Integrator key are hardcoded .
// Enter your DocuSign credentials:
String UserName = "abc#xxx.com";
String Password = "abc";
String IntegratorKey = "****************************";
Soon,the code will be moved to production org. When end users started using esignature process, same credentials (Username and password. Example above username and password) can be passed to connect to DocuSign API everytime or the user specific credentials should be passed to connect to Docusign APIs? What is the the best approach for this ? Any ideas.
Thanks.
It sounds like you want to create and send envelopes on behalf of other users. You will use a generic api account user which will authenticate with the API but you can use SOBO to send the envelope on behalf of another docusign sender that is part of the same account.
For Authorization Grant:
https://www.docusign.com/developer-center/explore/features/sobo
Easier way using the Authentication Header: https://docs.docusign.com/esign/guide/authentication/sobo.html

Are there security concerns exposing the clientId and tenant in client side code when using adal/adal-angular.js

I'm in the process of implementing AAD single sign on in our application and we will be using the adal.js/adal-angular.js library with our MEAN stack application. Part of initializing the library is to call init() and provide the tenant and clientId
adalProvider.init(
{
tenant: "mycompany.onmicrosoft.com",
clientId: "05bdd8d7-XXXX-XXXX-XXXX-5f2769f8b9b6"
},
$httpProvider
);
for example.
If someone views the source and takes the tenant and clientId can they use that somehow in their own application maliciously?
Does AzureAD check the URL the request came from and block it if it's not the configured login url?
Seems as though the clientId is more like a public key but if the only 2 things needed for an app to trigger authentication with AzureAD is the tenant and clientId and those are exposed client side in source code that someone could use them to create a phishing site X or to grab id_tokens if the request is redirected back to their site X rather than the original site
Does Azure rely on the configured settings in the application setup and protect against this?
I'm still getting a grasp on the OpenID Connect and OAUTH 2.0 finer points so forgive me if this question has an obvious answer.
Adal.js uses the Implicit flow (as per OpenID connect / oAuth 2 specifications) and exposing the ClientID (and tenant id of AAD) doesn't pose any security risk.
While registering the Clients in Azure AD administration panel, we specify a Redirect URI for the client. This is the Application URL for which users will get redirected after successful authentication.
So even if a malicious client tries to use your clientid and tenant id, the users will be redirected back to the registered URI(which is your app) after authentication and not to the malicious site
In implicit flow the application doesn't collect any username / password, IDP/OP (i.e AAD) manages this part - so user credentials won't be compromised as well
**For other flow types (Authorization code, Client credentials,etc) we have something called client-password along with ClientID. This shouldn't be exposed to public clients.

Resources