Reputation: 1961
Environment: Azure, Azure AD Free Licence;
I have built an ASP.NET Core 3.0 Web API and is hosted in Azure App Service. It's set to have OAuth Implicit Grant flow
where the token is used in the Authorization header as bearer
. So far everything works well; From token generation to authorization to authentication of Web API.
I have set up it as:
public void ConfigureServices(IServiceCollection services)
{
services.AddAuthentication(AzureADDefaults.BearerAuthenticationScheme)
.AddAzureADBearer(options => {
var readAzureAdFromEnvironment = Environment.GetEnvironmentVariable("READ_AZUREAD_FROM_ENVIRONMENT");
if (!string.IsNullOrEmpty(readAzureAdFromEnvironment) && readAzureAdFromEnvironment.ToUpper().Equals("TRUE"))
{
var INSTANCE = Environment.GetEnvironmentVariable("INSTANCE");
var DOMAIN = Environment.GetEnvironmentVariable("DOMAIN");
var TENANTID = Environment.GetEnvironmentVariable("TENANTID");
var CLIENTID = Environment.GetEnvironmentVariable("CLIENTID");
options.Instance = INSTANCE;
options.Domain = DOMAIN;
options.ClientId = CLIENTID;
options.TenantId = TENANTID;
}
else
{
Configuration.Bind("AzureAd", options);
}
});
services.Configure<Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerOptions>(AzureADDefaults.JwtBearerAuthenticationScheme, options =>
{
options.Events = new Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerEvents
{
OnTokenValidated = OnTokenValidated
};
options.RequireHttpsMetadata = false;
options.TokenValidationParameters = new Microsoft.IdentityModel.Tokens.TokenValidationParameters()
{
ValidateIssuer = false,
ValidateAudience = false
};
});
services.AddControllers()
.AddFluentValidation(s =>
{
s.RegisterValidatorsFromAssemblyContaining<Startup>();
s.RunDefaultMvcValidationAfterFluentValidationExecutes = false;
});
services.AddLogging(loggingBuilder =>
{
loggingBuilder.AddConsole();
loggingBuilder.AddDebug();
loggingBuilder.AddAzureWebAppDiagnostics();
});
services.AddApiVersioning(x =>
{
x.DefaultApiVersion = new ApiVersion(5, 0);
x.AssumeDefaultVersionWhenUnspecified = true;
x.ReportApiVersions = true;
x.ApiVersionReader = new HeaderApiVersionReader("x-api-version");
});
}
I learned that the default OAuth setup to ASP.NET Core is also
Implicit Grant type.
However, given the context that the consumer requires to integrate with an automation flow, it seems it's not feasible to manually input the credentials and get a new token every time the token expires.
I also learned that both; Implicit and Auth-Code require
access_token
as its final phase.
What I have done so far:
I was able to generate an access_token
by using oauth2/v2.0/token
endpoint with a client secret
and use the token for bearer
in the Authorization header and it worked. However, I noted that I couldn't get the logged-in user-id. I used the following:
client_id: "xxxxxxxxxxxxxxxxxxxxxxxx" grant_type: "client_credentials" client_secret: "xxxxxxxxxxxxxxx" scope: "api://xxxxxxxxxxxxxx/.default"
Did a little research and found that Authorization Code Grant flow
is ideal for this scenario given that it can produce a refresh token
and the same can be used when the token expires without prompting for the user credentials.
To change from Implicit to Auth-Code Grant
what should I do? I have few questions hope someone could help me in
Refresh_Token
? does this involve a code change or configuration change in Azure Active Directory?Azure AD Free licence
?Appreciate it if a Sample code can be given.
Upvotes: 0
Views: 876
Reputation: 58723
You are not using implicit grant if you are calling token endpoint. Implicit gets tokens from the authorize endpoint. That is client credentials grant what you are using, asking for a token for an application with no user involved.
Your API is configured to accept access tokens as it should be.
Your front-end application can use implicit grant or authorization code grant to get the access token it needs to call the API. No secrets are involved with these, unless you use authorization code grant from a back-end Web application.
Typically a front-end Javascript app would use MSAL.js to authenticate the user and acquire access tokens. These access tokens include user info, unlike the tokens you got with client credentials grant. MSAL.js 1.x will use implicit grant and 2.x will use authorization code grant with PKCE.
Refresh tokens are only returned with authorization code grant out of these two. Implicit grant does refresh using a hidden iframe and depends on the user having an active session with Azure AD. There isn't anything that you have to configure for this, it just depends on the flow you use if you get one or not.
Azure AD free does not limit you in these authentication flows. Not having one of the paid licenses means you can't use some of the features in Azure AD, like for example the ability to add a group into a role in an app.
You should consider in your back-end if you want to allow both of these types of callers to access it: client credentials grant using applications with no user and implicit/authorization code grant using applications that include a user. Client credentials grant using apps use "application permissions" or "app roles" that you have to check for, and the other apps use "delegated permissions" or "scopes" that you also need to check for. In addition to that an application using delegated permissions always involves a user, so you may need to also authorize the user's access to the resource being requested.
Upvotes: 1