Skip to content
This repository has been archived by the owner on Dec 4, 2024. It is now read-only.

dpolec/AzureAuth

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

11 Commits
 
 
 
 
 
 
 
 

Repository files navigation

AzureAuth

1 configure app in ad 1 configure authorizatoin in Web API 1 autorize from one API to another in delegated scoped

ADD SOME INTRODUCTION

Create Web API, remove example endpoint, and add for now only two endpoint to veryfied authorization:

var builder = WebApplication.CreateBuilder(args);

var app = builder.Build();

app.UseHttpsRedirection();

app.MapGet("/no-auth", () => Results.Ok());
app.MapGet("/auth", () => Results.Ok()).RequireAuthorization();

app.Run();

When we send request to no-auth we received 200, but when we send to auth we received 500

image

This is fine, because we don't setup authorization. Now we need create new application on portal.azure.com. Open service Azure Active Directory, in Manage section find APP registration, click on New registration

image

After creation in Manage section select Exponse an API, and set Application ID URI

image

Add scope

image

Assign scope to application, from Overview copy Application (client) ID, and assign scope to application

image

This configuration for now will be enought to autorize request. In Web API add package:

  • Microsoft.AspNetCore.Authentication
  • Microsoft.AspNetCore.Authentication.JwtBearer
  • For builder service we need configure middelware for authorization

    builder.Services
        .AddAuthorization()
        .AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
        .AddJwtBearer(options =>
        {
            var tenantId = "31dc6402-0301-47e7-906b-c64a780a7311";
            var audience = new List<string> { "api://3245fc3f-917a-4926-a3b6-778ce877047b" };
    
            var authority = string.Format(CultureInfo.InvariantCulture, "https://login.microsoftonline.com/{0}", tenantId);
    
            var configManager = new Microsoft.IdentityModel.Protocols.ConfigurationManager<OpenIdConnectConfiguration>(
                $"{authority}/.well-known/openid-configuration",
                new OpenIdConnectConfigurationRetriever());
    
            var config = configManager.GetConfigurationAsync().GetAwaiter().GetResult();
    
            var tokenValidationParameters = new TokenValidationParameters
            {
                ValidAudiences = audience,
                ValidIssuers = new List<string>
                {
                    $"https://login.microsoftonline.com/{tenantId}/",
                    $"https://login.microsoftonline.com/{tenantId}/v2.0",
                    $"https://login.windows.net/{tenantId}/",
                    $"https://login.microsoft.com/{tenantId}/",
                    $"https://sts.windows.net/{tenantId}/"
                },
                IssuerSigningKeys = config.SigningKeys
            };
    
            options.TokenValidationParameters = tokenValidationParameters;
        });
    

    Now add middelware:

    app.UseAuthorization();
    app.UseAuthentication();
    

    To veryfied this we need add some user to AD. In Azure Active Directoryt in Manage section select Users

    image

    What next, we need capability to create token, again go to our application and we need create client secret, in Manage section select Certificates & secrets, save this, because this value will be availble to read only after creation, we will need this to create token.

    I will be used PostMan and I add how configure this, but you can used any others rest client, or create in application.

    PostMan configuration

    In Authorization tab chose OAuth 2.0 type

    image

    In Configure New Token fill all data

    1. Token name
    2. Grant type -> Authorization code
    3. Callback url -> this will be setup automaticly, but to worked we need add this url to our application

    In Manage section, select Authentication -> Add a platform -> Web -> past redirect url -> Configure

    image

    image

    1. Auth URL -> https://login.microsoftonline.com/{TenantId}/oauth2/v2.0/authorize
    2. Access Token URL -> https://login.microsoftonline.com/{TenantId}/oauth2/v2.0/token
    3. Client ID -> you will find this on overwiev in application

    image

    1. Client Secret -> generated in application (Manage -> Certificates & secrets)
    2. Scope -> generated in application (Manage -> Expose an API), and you need add /.default (eg. api://3245fc3f-917a-4926-a3b6-778ce877047b/.default)
    3. State -> can be empty
    4. Client Authentication -> Send as Basic Auth header

    image

    Now we can generated token, we need login to AD using user credential

    Ok, we have API, we have configured application and user in AD, and setup rest client, you can check this, all should works fine.

    image

    Great! Usually this is enought. Now I will show how we can authorize in delegated scope (user scoope) from one API to second, lets call them Can auth API. We have one API, we need add new one, we need add in the same way how we added first. In our rest client change configuration for new API, we need change client id and secret, leve scope, beacue we want create token to authorize in Main API. We still can't create token, now we need told in first API that this second can authorize, copy application id from Can auth API and go to Main API. In Manage section, select Expose an API and add again client with scoped.

    image

    Somtimes we need wait some time, when this will be propagate, and start works. When you will try now create token, all will be works fine, and request will be authorized.

    image

    Next case it will be authorize token created for application, this is very common approach when one API need get some data from other API. Create token for application is very easy, we need just send request as POST to url https://login.microsoftonline.com/{tenantId}/oauth2/v2.0/token and in body as form data:

    client_id: 8b001c8d-c64b-42b5-bf37-d8e97a58110e
    client_secret: MHY8Q~Kp3kUQ~L1Rp2zWY0LpvW6xVZrzip_D3cKe
    grant_type: client_credentials
    scope: api://3245fc3f-917a-4926-a3b6-778ce877047b/.default
    

    In response we received access token, and we can use it in request to authorize, but for now we have one secure breach, to undersand this we need create again new app, lets call them Can't auth API. Now we can generete in the same way application token, and we can authorize in Main API, where Main API don't know anything about Can't auth API application. To manage this we have something like App roles, role can be dedicated to permission only for user or application, or all. In app roles we can ach of this role we can use to separete endpoint. We can create mutiple app roles, each role can be assign to different endpoint, that we can decide which api has access to which endpoint.

    Ok, so lets do this, and check.

    First create app role

    image

    I call FirstRole, for both approach

    image

    Ww need add this role to application where we want. To do this we need go to Can Auth API to section API permissions and add this role.

    image

    image

    image

    in status we will see that is Not granted for ...

    image

    We can add permission, but we need approved for active directory administrator, now if you are this adm then you can do this, you will be decide wich endpoit can have this role. But if you are working in bigger comapny, I supposed that you have dedicated administraotr, and we need ask him/her to grant this. In app where we need grant this in API permissions we will have special option to do this

    image

    Ok, now we need to handle the role we added in the code, I will added new one endpoint to do this, we need register authorization policy, and add this policy to endpoint.

    var builder = WebApplication.CreateBuilder(args);
    
    builder.Services
        .AddAuthorization(auth =>
        {
            auth.AddPolicy("role-type-policy", policy => policy.RequireRole("FirstRole"));
        })
        .AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
        .AddJwtBearer(options =>
        {
            ...
        });
    
    var app = builder.Build();
    
    app.UseHttpsRedirection();
    
    app.MapGet("/no-auth", () => Results.Ok());
    app.MapGet("/auth", () => Results.Ok()).RequireAuthorization();
    app.MapGet("/first-role", () => Results.Ok()).RequireAuthorization().RequireAuthorization("role-type-policy");
    
    app.UseAuthentication();
    app.UseAuthorization();
    
    app.Run();
    

    ToDo

    1. add app role (add to 1 app)
    2. example how auth request base on role in scope user
    3. example how auth request in scope of app
    4. how secure request in scope of app
    5. maybe section prepare I will don't split?

    what we can do more

    1. certificate

    About

    No description, website, or topics provided.

    Resources

    License

    Stars

    Watchers

    Forks

    Releases

    No releases published

    Packages

    No packages published

    Languages