Get access token for Microsoft Graph - c#

I have a web application in C# through which I'm trying to get access token for Microsoft Graph API. I'm able to get tokens through using Client secret, but don’t want to get the token by using the client secret but get the token by other means, want to get tokens without client secrets.
I'm successfully getting the tokens using secrets and have stored them in KeyVault but getting an alert for "Explicit Credentials are being used for your application/service principals", so require some alternative to get tokens.
Is there any way to get tokens without secrets. Any help would be great.

One can use ROPC oAuth grant based on username and password instead of using Client Secrets to get access tokens. Microsoft identity platform supports the OAuth 2.0 Resource Owner Password Credentials (ROPC) grant, which allows an application to sign in the user by directly handling their password. Refer, https://learn.microsoft.com/en-us/azure/active-directory/develop/v2-oauth-ropc
Warning:
Microsoft recommends you do not use the ROPC flow. In most scenarios, more secure alternatives are available and recommended. This flow requires a very high degree of trust in the application, and carries risks which are not present in other flows. You should only use this flow when other more secure flows can't be used.

It is not a recommended way to use without client secret since due to security concerns.
If you still don't want to use client secret go with implicit grant flow which we can easily implement on the front end by maintaining SPA and passing token to the backend

Related

How to restrict accounts in token based authentication

I'm tasked with authenticating an access token being passed by a react client in my .net core API. The access token in question is issued by google. Now I'm trying to figure out how to structure my API such that the endpoints are restricted to a predetermined set of google accounts. What is the best way and best practice to go about enforcing the restriction? Should I store a set of google IDs in my database and check the google Ids against the payload of the token being passed by the client? I'm relatively new to the whole concept of OpenID and OAuth and authentication so I'm not sure if the process I described follows specifications. Any help is appreciated.

Authenticate User In Azure AD (validate username & password) via Azure Functions

Is it possible to create an Azure Function which will take username and password as input parameters and function should validate user against Azure AD.
Firstly, it's important to mention that collecting username and password for an Azure AD user as part of your application (Azure function or web app any other application you're developing) is very much against the best practices and opens up multiple attack risks. So even though you may be able to use workarounds to achieve it, please do reconsider the requirement that you have from a security standpoint.
Workaround - ROPC - Resource Owner Password Credentials Grant (Not recommended, multiple issues)
Azure AD does not provide a direct API to validate user credentials. As a workaround (and a bad one at that), you can use Resource Owner Password Credentials (ROPC) flow which works with username and password to acquire a token.
It violates security best practices and also does not work with MFA and federated authentication users. Using this grant is highly discouraged as it brings potential attack risks, so not recommended.
If either username or password is incorrect, you will get an exception, otherwise you get back a valid token which means credentials are good.
Here are a couple of links that cover details on ROPC (and recommend not using it at the same time..):
ADAL.NET library documentation on acquiring tokens with username and password
Resource Owner Password Credentials Grant in Azure AD OAuth
For example, code would look like this for a native application.
result = await context.AcquireTokenAsync(resource, clientId, new UserPasswordCredential("john#contoso.com", johnsPassword));
Other references
Here is an old article but still very detailed. And look at the long list of limitations at the end.

use WindowsIdentity/WindowsPrincipal to get SAML token for WS-Federation

Is there a way to use the native WindowsIdentity/WindowsPrincipal inside of a C# application running on a corporate domain to be able to request a SAML token from the domain's ADFS server so that the C# application can then make subsequent calls to WS-Federation calls in a service provider that has been federated with the ADFS server?
Seems like we would use WIF to contact the ADFS server to get a token. Is there a way to supply a Kerberos ticket to the WIF, rather than using a username/password?
Looking at WindowsIdentity.GetCurrent() I can see that the user is logged in using kerberos, but don't see how to configure the WIF call to ADFS to use kerberos to automatically get a SAML token without a username/password set of credentials.
Does https://blogs.msdn.microsoft.com/alikl/2011/09/30/how-to-use-ad-fs-endpoints-when-developing-claims-aware-wcf-services-using-wif/ help?
You should make sure you have an endpoint enabled that can do windows integrated auth via kerberos enabled. Something like /adfs/services/trust/2005/windowstransport or /adfs/services/trust/13/windowstransport . You can check that via parsing the /adfs/services/trust/mex endpoint. Occasionally some of these endpoints are disabled by a sysadmin.
Using a kerberos ticket as the credential for the endpoint means your app needs to be running on corpnet with access to domain controllers so it can obtain a ticket for AD FS. If the app use is not required outside corpnet this might be OK for you. Else you need to consider how the app behaves/authenticates inside and outside corpnet.
Have a look at https://www.microsoft.com/en-gb/download/details.aspx?id=4451 for samples but they'll need modifying based on version of WIF you plan to use as outlined in https://learn.microsoft.com/en-us/dotnet/framework/security/guidelines-for-migrating-an-application-built-using-wif-3-5-to-wif-4-5
Lastly you should consider if its possible to use OpenID Connect and OAuth2.0 instead of WS-Federation/WS-Trust in your scenario. If yes, you should review the information at https://learn.microsoft.com/en-us/windows-server/identity/ad-fs/overview/ad-fs-scenarios-for-developers

How Resource Server can identify user from token?

I'm trying to understand how OAuth 2 works.
I don't understand this thing: if Authorization Server and Resource Server are not the same system, as in this image:
How the resource server can know who is the user and what are his permissions?
Can I retrieve these information from the Access Token or I must have a back-end comunication between Authorization Server and Resource Server?
Depends on the type of token as to how it's consumed by the resource server.
Self encoded access tokens tokens (e.g. JWT bearer tokens) will contain all the user and scope information in the token. Or some Auth systems use token introspection as detailed in Jan's answer.
This is a good introduction to the resource server and the types of token.
And a very common self encoded token is the JWT Token.
Taking the example of a self-encoded access token:
The Access Token will contain the user identifier and scopes / permissions for the token issued in the example above - which is the "implicit" grant type.
The Resource server should not need to contact the auth server. This can be one of the key benefits of Oauth 2.0 for APIs. It must trust it though. It should confirm the token has been signed by the auth server, and it may also need to be able to decrypt the token, if encrypted by the auth server.
Obviously the resource server needs to be able to access the data for the user in the token. It may be that the auth server and resource server point to the same underlying database.
Access token is usually a randomly generated string, so you cannot read any information out of it (but there may be OAuth2 implementations that use some meaningful values). The resource server must validate the access token and its scopes, not the permissions of the user who was authenticated before creating the token (resource owner). That's an important detail, because OAuth2 is a protocol for permission delegation from a resource owner to a client in form of an access token and its scopes. To do that, the resource server needs to make an HTTP request to the Token Introspection endpoint of the auth server. The JSON response contains
Boolean flag active that says whether the access token is still valid (not revokend, not expired)
Parameter scope holds its scopes granted by the resource owner
username of the resource owner
Some other useful fields.
The resource server should check that the access token is active and that it contains scopes required by the requested resource or service. It may perform some other validations (such as the requested resource is owned by the resource owner identified by the username field).
The introspection response for a given access token may be cached by the resource server (to improve performance). See the RFC for security considerations.
Access token may self-contain the authorization information in a verifiable manner (for example signed JWT). In such case, the resource server should be able to verify the authenticity (signature) and scopes of the token without calling the auth server, but then it's hard to implement the token revoke endpoint, since the resource server would accept a token even if it gets revoked at the auth server.
It can be complicated. There are many different implementations and combinations relationships between the User, Application and Resources.
Perhaps a more descriptive explanation of your architecture and relationships between the entities involved would be helpful.
If you are trying identify the User, then OAuth is not the correct protocol. YOu should look into OpenID Connect or User-Managed Access.
Generally the Resource server would only need to know the scopes to be able to provide access. Not the Identity of the user.
-jim

How to authenticate user with Azure Active Directory using OAuth 2.0?

I have a REST API written in C# and I need to authenticate with an existing Azure AD service. I currently have the username and password of the user wishing to authenticate. I need to authenticate with Azure AD and receive an access token from the server.
Can someone please point me in the direction of some articles/tutorials that explain how to do this?
You should avoid handling the users credentials. There are serious security implications when collecting a users credentials that are mitigated by using OAuth 2.0 or OpenID Connect to get a token without directly handling the credentials. Also, if you have your own credential collection UI then you may find that sign in fails in the future if multi-factor authentication is turned on. In that case, more information may be necessary to authenticate the user than you are collecting, a one time password for instance. If you allow Azure AD to present the authentication experience via OAuth 2.0 or OpenID Connect, then you are insulated from the specific authentication method being employed. Collecting the users Azure AD credentials is a bad practice to be avoided if at all possible.
I don't have enough detail on the exact scenario to be confident that the following sample applies, but it will at least provide a good starting point. This sample shows how to create a native app that calls a REST API that can then call an Azure resource in the safest way possible.
https://github.com/AzureADSamples/WebAPI-OnBehalfOf-DotNet
You can find lots of other samples here that can be used to construct a solution for your particular scenario.
https://github.com/AzureADSamples
If you provide some more detail I can give more specific guidance.
See: http://www.cloudidentity.com/blog/2014/07/08/using-adal-net-to-authenticate-users-via-usernamepassword/
Summary:
Create a UserCredential
UserCredential uc = new UserCredential(user, password);
Call one of the AcquireToken() functions with the UserCredential
public AuthenticationResult AcquireToken(string resource, string clientId, UserCredential userCredential);
public Task<AuthenticationResult> AcquireTokenAsync(string resource, string clientId, UserCredential userCredential);

Categories

Resources