I have a button on dynamic CRM. On click of this button I need to navigate to a .net core Web App showing the other details. Currently I have implemented AD Authentication and every time it navigates from CRM to web app, it will ask me for login with my AD credentials.
Instead I need to implement Single Signon mechanism where web app is to be automatically authenticated with same credentials I logged into my CRM. (CRM and web app is already under same tenant of Azure Active Directory).
Can someone help me in achieving this or provide me any sample application.
Ensure prompt=none is appended to your auhorization request URL. E.G:
// Line breaks for legibility only
https://login.microsoftonline.com/{tenant}/oauth2/v2.0/authorize?
client_id=6731de76-14a6-49ae-97bc-6eba6914391e
&response_type=code
&redirect_uri=http%3A%2F%2Flocalhost%2Fmyapp%2F
&response_mode=query
&scope=openid%20offline_access%20https%3A%2F%2Fgraph.microsoft.com%2Fmail.read
&state=12345
&prompt=none
I have a C# class library from which I am trying to add an event to someone calendar just by using his/her email address and password as credentials. So I debug it and once started a new page in the internet browser is open and below error is displayed:
Below the code:
// It crashes when calling GoogleWebAuthorizationBroker.AuthorizeAsync
UserCredential credential = GoogleWebAuthorizationBroker.AuthorizeAsync(
new ClientSecrets
{
ClientId = "myGoogleAccount#gmail.com",
ClientSecret = "myGoogleAccountPasswordHere",
},
new[] { CalendarService.Scope.Calendar },
System.Environment.UserName,
CancellationToken.None).Result;
// Create the service.
var service = new CalendarService(new BaseClientService.Initializer()
{
HttpClientInitializer = credential,
ApplicationName = "Calendar API Sample",
});
Why this error is happening? ClientId is not the gmail account?
Also why a new page in internet browser is opened? I want to do authentication without opening a page in the internet browser because this class library is called from a windows service so I need authentication to be done in the background.
Answer:
In order to insert methods into a user's Calendar, you need the user to give your application permission to make actions on their behalf. This is done using a Google Cloud Platform (GCP) Project, with OAuth2 Authentication.
More Information:
Each application which runs and takes actions on behalf of a Google account user has to have the scope of its ability well defined so that it can't start doing things that a user hasn't given it permission to do.
For example: if you give an application permission to create Calendar events, you don't want it to be able to do other things such as read your emails or download the contents of your Drive.
In order to designate what your application has the power to do, it needs to be registered with Google. As you have already deduced in your question and comments, the Client ID and Client Secret required by an application connecting to a G Suite API isn't simply the username and password of a Google Account, but a designated ID-secret ID pair which is provided by Google to identify your application.
OAuth2:
OAuth2 is a specific authorisation framework. The framework is defined in RFC 6749 and sets out the process in which a user can authorise an application to access their account. The limit of the authorisation is defined by the scope of the application on authorisation, and can not be changed without explicit re-authorisation by the user.
Before continuing it's worth defining a few important terms here:
User:
A user is the person; the individual that has an account and gives permission for an application to take actions on their behalf.
Client or Application:
A Client or Application is a program which is designed to take actions over HTTP by connecting to a service's API. Applications can be mobile apps, web apps or desktop clients.
Authorisation Server:
An Authorisation server is a server which is separate from the servers that store user resources. It verfies the user's identity and provides a grant which can be used to get an access token to a resource server.
Resource Server:
This is the server where user data is stored. This could be anything from user information to files or emails.
The authorisation flow has already been well documented, but for the sake of this scenario we can abstract it down to the following steps:
An Application wishes to take an action on a resource server on behalf of a user.
The Application makes an authorisation request to the user. This is generally presented as a login page for the account for which the application is accessing.
The user logs in to their account and is presented with an OAuth consent screen - this contains information such as the application's name, and the list of tasks that it is requesting authorisation for. These are often generic, and will say something like See and download all your Google Drive files or View and edit events on all your calendars. This allows the user to know what they are authorising before they confirm.
An Authorisation Grant is given to the application.
The Application provides the obtained authorisation grant along with its assigned client credentials to an authorisation server.
On verifying that both the user's grant and the client's credentials are correct, the authorisation server returns an access token which can be used to access the requested and approved resources. Note: This is normally all handled by your client library for whichever language you use.
The Application can now make a request to the resource server, providing the access token obtained from the authorisation flow. It is at this point that the permitted resources can be accessed.
Google Cloud Platform Projects:
A GCP project what Google sees as your application. The registration for your application is required to be able to obtain the client ID and client secret which your application will need in order to get an access token in the authorisation flow.
In the GCP console you can set up all the required services that your application needs. Each API you wish to use has to be enabled for your application, as there are many Google services with APIs and they are disabled by default.
Once a GCP Project has been created, you can use the API Library (From the ≡ > APIs & Services > Library menu item on the left) to find and enable the API. Note that for your use case you will want to enable the Google Calendar API and not the CalDAV API.
You will also need to set up a consent screen before obtaining credentials for your application. An OAuth consent screen is what your users will be presented with in the first step of the OAuth flow:
When setting up your OAuth consent screen, you will need to provide the following information:
Application type (public or internal to your domain)
Application name
The scopes that your application needs (explained in the next section)
After the consent screen has been set up, you can download the client credentials for your application. With these, your application has permission to run as a client, but each user that has their resources accessed will still have to give their explicit permission to allow the application to do so.
Scopes:
Within a single API there can be many scopes of access - having read-only access to calendar events is vastly different to having complete read-write access to all calendars that a user owns. This is where scopes come into play.
A scope is defined as its namesake; that is to say, a scope defines the scope of access an application has to a service. Even though an entire API has been enabled for a project doesn't mean that you need to use all features of the API. For this reason, scopes need to be defined.
Scopes are defined in the application itself before making the initial request for the user grant. In C#, for example (taken from the .NET Calendar API Quickstart):
// scopes are defined as an array of strings:
static string[] Scopes = { CalendarService.Scope.CalendarReadonly };
...
UserCredential credential;
credential = GoogleWebAuthorizationBroker.AuthorizeAsync(
GoogleClientSecrets.Load(stream).Secrets,
Scopes,
"user",
CancellationToken.None,
new FileDataStore(credPath, true)).Result;
The access token that is stored is based on the scopes that were defined in the call. If a method is called which needs a different scope to those which the token grants access to, the call will fail with a 403: Unauthorized error. The required scope will need to be added to the application, the old access token deleted and the user will need to grant permission for the new scopes.
Service Accounts:
As well as regular users, there is another special type of Google account called a Service Account. From the documentation:
A service account is a special kind of account used by an application or a virtual machine (VM) instance, not a person. Applications use service accounts to make authorized API calls.
Normally, every user for whom you wish to perform tasks or access resources needs to give explicit permission for your application to do so. For G Suite domains, however, you can use a service account with domain-wide delegation to complete tasks on behalf of users without the requirement.
Service accounts use a special kind of service-account credential which can be created in GCP and used in your application. Rather than making a UserCredential object, a ServiceAccountCredential is needed which doesn't require involvment by an end user.
When running a service account on behalf of a user with domain-wide delegation, the name of the user needs to be specified in the delegated credentials so the application knows which user in the domain to run as. If a user is not provided, the service account will run the code as itself; which is useful in some cases but often times will not return an error and so it may not be clear for whom the operation was run.
Note: While Service Accounts can be created by anyone, domain-wide delegation of authority can only be accomplished for a G Suite domain, and not #gmail.com addresses. All Gmail account users must give explicit permission for an application to run on thier behalf as set out by the OAuth flow.
References:
Using OAuth2 to Access Google APIs | Google Identity Platform
RFC 6749 - The OAuth2 Authorization Framework
OAuth - Wikipedia | #OAuth2
Google Cloud Platform Console
Google APIs Explorer | Google Developers
.NET Quickstart | Calendar API | Google Developers
Service Accounts | Cloud IAM Documentation | Google Cloud
Perform G Suite Domain-Wide Delegation of Authority | Directory API
OAuth 2.0 | API Client Library for .NET
Related Questions:
Google API Service Account. Can only see service accounts drive even with Domain Wide Delegation Access
Creating events using the Google Calendar API and Service Account
I'm trying to plug Azure AD Authentication to my MVC project.
and each time I try to connect the service these errors appear to me.
I checked the previous authentication into "packages.config" -"Web.config" and everything is clear.
also, I checked the client id, clientSecret, Redirect URL, Azure Domain and everything was right!!
what's is the problem here so I can't move forward with it?
Actually this kind of service linking Azure AD with needs permissions more that User.Read ,
because maybe it will change something in the Azure AD App.
so I change the project to authorize directly to Azure AD without that Service by edit the code manually.
I noticed that were adding Read directory data permission to the application. So you must have checked the permission when configure Azure AD Authentication.
Try to login Azure portal with the account which you used to configure Azure AD Authentication in Visual Studio. Find your application and check if you can add Directory.Read.All permission successfully.
If you can add it successfully, try to create a new Azure AD application when configure Azure AD Authentication.
I have access to my Azure AD Portal. I also have an external ASP.NET application which is accessing the Microsoft Graph API. For this purpose I add an App Registration which give me an Application ID and Key to be able to configure my ASP.NET application to authenticate itself against the Graph API.
I need the my ASP.NET application to read groups out of Azure AD. I can authenticate successfully but I get an error saying that I have not enough privileges. Then I go back to the Azure Ad Portal and add permissions to the App Registration I added. This works ok so in the end I have the Graph API response on my ASP.NET application.
Now it comes the issue. I selected too many permissions so I want to use the smallest set of permissions that are necessary for my ASP. So I go the Azure Portal AD again and remove some of the permissions. When I test my app again, I still receive the groups even if I have no permissions selected.
I think this is an issue. Or there's some kind of delay? I don't think so because when the API is working and has the proper permissions I can add a group in Azure AD Portal and instantly see it in my ASP.NET application.
This issue is specially annoying because you can't really test the permissions your app needs.
Thanks.
Is there a mechanism in Azure AD to have a completely headless authentication? Most likely this would mean (in my mind) that the server running the API would have a perpetual authentication session to Azure.
If the purpose matters... We have a need to expose our thumbnailImage attribute from AD and I just need to make it so that the server doesn't care who requests the image. So basically we will have https://domain.com/api/Image/userid and the api will return an Image object (image/jpeg). I have this functioning internally and now I'm just migrating to Azure.
I found this question... I just want to confirm two things...
Daemon or Server Application to Web API is the method I should be looking at
Using this method will function as I'm expecting... a.k.a. WebAPI can access that attribute and use it like I currently use it while inside our internal domain.
Indeed. Azure AD supports the client credential OAuth flow. Yes, you are looking at the right help topic. The corresponding sample application is here: https://github.com/AzureADSamples/Daemon-DotNet.
If you haven't already, use Azure management portal to register your WebAPI as an application in your Azure AD directory and add a client secret (under the section named 'key' in the 'configure' tab of the 'application'). This key will be used as the client credential.
To configure permissions for your WebAPI to be able to call Graph API using client credential flow token, go to the application tab in the Azure Portal, under Azure AD and in the section titled 'Permissions to other applications', add an 'Application Permission' to 'Windows Azure Active Directory' to 'Read directory data'.
What you refer to as perpetual authentication session is basically your WebAPI caching the access token to Graph, and getting a new access token (using client credential flow) when the current access token is about to expire.
Hope this helps.