Perhaps the question is more comprehensive than the title. There are a lot of posts about Authentication, tokens, JWT, Azure AD, etc. but all these posts seem to tell a different story which make the basic concept, at least to me, a bit unclear. I'll try to explain my questions using my case.
I have build a Frontend application with React in Visual code and a Backend application in Visual Studio .Net Core 2 (Web API). The application are being hosted in Azure and we would like to do authentication with Azure AD.
The frontend uses Adal-React (https://learn.microsoft.com/en-us/azure/active-directory/develop/active-directory-authentication-libraries) and Axios (https://github.com/axios/axios).
With the help of tutorials I have set up the configuration in the Frontend and in the API (backend), using namely the TenantID and ClientID which are listed in the Azure environment.
Although I have set it up and it is working, the way how it works is more or less unclear to me.
I'll try to explain the current workflow in my applications as it now is and listed my current questions below:
1 - The user navigates to the frontend application, adal checks if the user is authenticated and if it is not the person is redirected to our azure login environment, this is set up in the adal config (frontend) as follows:
const adalConfig = {
tenant: 'vhsprod.onmicrosoft.com',
clientId: 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxx',
endpoints: {
api: 'https://xxxxx.onmicrosoft.com/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxx (client id)',
},
postLogoutRedirectUri: window.location.origin,
redirectUri: 'http://localhost:3000/user-form',
cacheLocation: 'sessionStorage'
};
export const authContext = new AuthenticationContext(adalConfig);
export const getToken = () => {
return authContext.getCachedToken(authContext.config.clientId);
};
2 - the user needs to login and is being checked if the user exists in the Azure AD environment, if so, then the user gets redirected back to the frontend and we got our self a token.
3 - The user opens a form / page in the frontend which requires data from the backend, a API call is being made with the just received token. The call is being done using Axios in the frontend, Axios is also configured:
export const axiosCallToMyAPI = axios.create({
baseURL: 'http://localhost:52860/api/',
timeout: 5000,
headers: {'Authorization': 'Bearer ' + initialToken}
});
The initial token is being received from Adal, the token we just received:
let initialToken = sessionStorage.getItem('adal.idtoken')
4 - The call is being made to the API and here we have also set up the configuration (appsettings.json) for using Azure AD:
"AzureAd": {
"Instance": "https://login.microsoftonline.com/",
"TenantDomain": "xxxx.onmicrosoft.com",
"TenantId": "xxxx.onmicrosoft.com",
"ClientId": "xxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxx"
}
5 - In the startup class of the API the token is being validated:
services
.AddAuthentication(sharedOptions =>
{
sharedOptions.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
sharedOptions.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
sharedOptions.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(options =>
{
options.Audience = this.Configuration["AzureAd:ClientId"];
options.Authority = $"{this.Configuration["AzureAd:Instance"]}{this.Configuration["AzureAd:TenantId"]}";
options.Events = new JwtBearerEvents()
{
OnTokenValidated = context =>
{
return Task.CompletedTask;
}
};
});
The questions that remain and the assumptions made by me (reading several posts) are the following:
- With the Azure token, which the frontend receives, a call to the API is being made, how does the API knows this token is 'valid'? I know the startup class of the API uses the event
OnTokenValidatedbut what is the magic behind this? Is it purely checking the configured Tenant / Client ID in theappsettingswith the token that is being received?? - In several posts they use/mention a SecretKey / Signing Key, in my example however I have not implemented the SecretKey, yet it still works. Do I need to implement the secret / signing key in my API (backend)? Is it necessary?
- I have also read up on Implicit flow, OpenID connect and some other terms. When using Azure AD authentication like in my example, and doing it this way, am I then automatically doing
implicit flow(frontend --> backend) and authentication withopenid connect? In other words, when using Azure authentication, are you then automatically doing these / the best practices, or should you still implement it? - The token has certain claims /. scopes defined which are being supplied by Azure (where you can also set these claims like email and roles), however when using AspNet (Identity) you can also add your own claims to the current token / session, for example when I add a roleclaim from aspnetidentity to my token. How do these claims differ from the original claim (still bearer / jwt?) and is this a good practice?
Could anyone confirm / explain these questions?
My apologies if the story is a bit to general, but at the moment our trial-error rate is way to high and I just am trying to clear things up.