GithubHelp home page GithubHelp logo

azure-samples / active-directory-dotnet-external-identities-api-connector-azure-function-validate Goto Github PK

View Code? Open in Web Editor NEW
26.0 18.0 17.0 422 KB

.NET Core Azure Function for use with API connector to validate user attributes on external user self service sign-up

License: MIT License

C# 100.00%

active-directory-dotnet-external-identities-api-connector-azure-function-validate's Introduction

page_type languages products description urlFragment
sample
C#
.Net core
azure-active-directory
A sample to demonstrate how to validating a sign-up user flow using a C# Azure Function and API connectors
active-directory-dotnet-external-identities-api-connector-azure-function-validate

User flow sign-up customization using C# .NET Core Azure Function and API connectors

This sample demonstrates how to use API connectors to customize sign-up for Azure AD guest user self-service sign-up and Azure AD B2C sign-up user flows. In particular, the sample demonstrates how to:

  1. Limit external user sign-ups to only a particular federated Azure Active Directory tenant. In this example, it's a fictitious fabrikam.com and fabricam.com.
  2. Validate a user-provided value Display Name against a validation rule.

The API is implemented using an Azure Function HTTP trigger in C# .NET Core.

Contents

File/folder Description
SignUpValidation.cs Sample source code for HTTP trigger.
ResponseContent.cs HTTP response content.
.gitignore Define what to ignore at commit time.
CHANGELOG.md List of changes to the sample.
CONTRIBUTING.md Guidelines for contributing to the sample.
README.md This README file.
LICENSE The license for the sample.

Key concepts

API connectors provide you with a way to modify and extend sign-up flows by leveraging web APIs. API connectors are available in both guest user self-service sign up and Azure AD B2C sign-up user flows.

This examples uses an API connector to limit sign-ups to only specific email domains, fabrikam.com and fabricam.com. This is easily modifiable in SignUpValidation.cs and can be extended limit sign ups to any particular email domain or set of email domains. Further, the API connector in this sample is used to perform input validation on Display Name by ensuring a user provides a value of at least 4 characters.

This sample uses an Azure Function as the web API endpoint but you can alternatively edit the .cs files in your preferred IDE and deploy that code in any web service. If so, environment variables used for authentication may work differently.

Prerequisites

Before you get started, make sure you have the following requirements in place:

Setting up your Azure Function

Steps to run locally

  1. Clone the repository
git clone https://github.com/Azure-Samples/active-directory-dotnet-external-identities-api-connector-azure-function-validate
  1. Navigate to the Azure extension in Visual Studio code on the left navigation bar. You should see a 'Local Project' folder representing your local Azure Function.
  2. Press F5 (or use the Debug > Start Debugging menu command) to launch the debugger and attach to the Azure Functions host. (This command automatically uses the single debug configuration that Azure Functions created.)
  3. The Azure Function extension will automatically generate a few files for local development, install dependencies, and install the Function Core tools if not already present. These tools help with the debugging experience.
  4. Output from the Functions Core tools appears in the VS Code Terminal panel. Once the host has started, Alt+click the local URL shown in the output to open the browser and run the function. You can also see the url of the Local Function by right clicking on the function on the Azure Functions explorer.
  5. To redeploy the local instance during testing, just repeat these steps.

Add authentication

Authentication is stored in environment variables, so they're not stored as part of the repository and should never be stored in checked in code. Read more about the local.settings.json file.

  1. Create a local.settings.json file
  2. Add the BASIC_AUTH_USERNAME and the BASIC_AUTH_PASSWORD setting.
  3. You final local.settings.json should look like following one:
{
  "IsEncrypted": false,
  "Values": {
    "AzureWebJobsStorage": "",
    "FUNCTIONS_WORKER_RUNTIME": "dotnet",
    "BASIC_AUTH_USERNAME": "<USERNAME>",
    "BASIC_AUTH_PASSWORD": "<PASSWORD>"
  }
}

Specify a Username and Password. This will be what your Azure Function uses to authenticate incoming requests.

Deploy the application

  1. Follow steps of this guide to deploy your Azure Function to the cloud. Copy the endpoint web URL of your Azure Function.
  2. Once deployed, you'll see a 'Upload settings' option. Select this. It will upload your environment variables onto the Application settings of the cloud.

To learn more about Visual Studio Code development for Azure Functions, see this.

Configure and enable the API connector

Follow the steps outlined in "Add an API connector" for guest user self-service sign-up or for Azure AD B2C to create an API connector and enable it your user flow. The end result is shown below.

API connector configuration

Your API connector configuration should look like the following:

API connector configuration

  • Endpoint URL is the Function URL you copied earlier.
  • Username and Password are the Username and Passwords you defined as environment variables earlier.

Enable the API connector

In the API connector settings for your user flow, you can select the API connector to be invoked at either step:

API connector select

  • After signing in with an identity provider - if enabled for this step, the API connector will only allow users with an email ending in @fabrikam.com. Note that for Azure AD B2C, this does not apply to local accounts.
  • Before creating the user - if enabled for this step, the API connector will only allow users with an email ending in @fabrikam.com and check whether the Display Name attribute is of at least length 5. Note, the Display Name has to be selected in User attributes for the user flow.

Customizing the Azure Function

This sample provides a quick way to get started using API connectors. By modifying the source code and leveraging all the capabilities of a web API you're used to, you'll be able to accomplish many more complex scenarios including integration with other web APIs and services.

Contributing

This project welcomes contributions and suggestions. Most contributions require you to agree to a Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us the rights to use your contribution. For details, visit https://cla.opensource.microsoft.com.

When you submit a pull request, a CLA bot will automatically determine whether you need to provide a CLA and decorate the PR appropriately (e.g., status check, comment). Simply follow the instructions provided by the bot. You will only need to do this once across all repos using our CLA.

This project has adopted the Microsoft Open Source Code of Conduct. For more information see the Code of Conduct FAQ or contact [email protected] with any additional questions or comments.

active-directory-dotnet-external-identities-api-connector-azure-function-validate's People

Contributors

helshabini avatar microsoft-github-operations[bot] avatar microsoftopensource avatar nickgmicrosoft avatar yoelhor avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

active-directory-dotnet-external-identities-api-connector-azure-function-validate's Issues

Continue content response with updated claim is ignored by Azure B2C Directory

I've registered an API connector during sign up user flow (before user creation). In some situations I like to update some claim that the user entered during sign up. Therefore my API does return a response content object created with the class below.
The problem is that the Azure B2C does ignore my continue response object. The created user object contains the streetAddress value that the user entered in the sign up form. My API receives that data when get called form B2C but I'm not able to override the value with "XXXXX" with my continue response object.

`
public class ContinueResponseContent
{
public const string ApiVersion = "0.0.1";

    public ContinueResponseContent()
    {
        this.version = ContinueResponseContent.ApiVersion;
        this.action = "Continue";
        this.streetAddress = "XXXXXXX"; //Test overriding the steetAddress claim the user provided during sign up 
    }

    public string version { get; }
    public string action { get; set; }
    public string status { get; set; }
    public string streetAddress { get; set; }
}

`
Help is welcome :-)

ResponseContent status property usage incorrect

The ResponseContent class's status property should be an int, as per here.

Additionally, calls using the ResponseContent constructor within a BadRequestObjectResult constructor that don't pass the 400 status (in SignUpValidation.cs, lines 51, 60, 66) results in AzureAD B2C returning a generic "Bad Request" message instead of the message used in the code. The 400 status should be passed (or make it the default value).

"ShowBlockPage" response is not working

trying to use the show blocking response in a sign-in flow connector
verified that the response from api which seems correct and looks like below

{
    "version": "1.0.0",
    "action": "ShowBlockPage",
    "userMessage": "You must have a local account registered for Contoso."
}

With this, was hoping to see a blocking page in b2c user flow, but it does not show it and goes straight to the connected application.

is there anything missing or this is not applicable for sign-in and works only with sign-up flows?

here is snippet responsible for sending this response back to b2c

// check for issuer
    if(data.identities != null)
    {
        string issuer = data.identities[0].issuer;
        log.LogInformation("issuer detected: " + issuer);
        if(issuer == "github.com")
        {
            log.LogInformation("Returning an error!");
            return (ActionResult)new OkObjectResult(new ResponseContent("ShowBlockPage", "You must have a local account registered for Contoso."));
        }
    }

Content Response ShowBlockPage is only working when version is set to "0.0.1"

I've registered an API connector during sign up user flow (before user creation). In some situations I like to abort the sign up process with an error message. Therefore my API does return a response content object created with the class below. I wonder why the Azure B2C Directory does ignore my content response when I set the version string to "1.0.0" instead of "0.0.1" According to the documentation the version string "1.0.0" should work as well. https://docs.microsoft.com/en-us/azure/active-directory-b2c/add-api-connector#example-of-a-blocking-response
However the documentation is not very clear. It states "The version of the API.". My API or the B2C Directory API Version?

`
public class ShowBlockPageResponseContent
{
public const string ApiVersion = "0.0.1";

    public ShowBlockPageResponseContent(string userMessage)
    {
        //this.version = ShowBlockPageResponseContent.ApiVersion;
        this.action = "ShowBlockPage";
        this.userMessage = userMessage;
        this.status = "400";
    }

    public string version { get; }
    public string action { get; set; }
    public string userMessage { get; set; }
    public string status { get; set; }
}`

Help is welcome :-)

Example code does not compile

It appears there are issues with ResponseContent.cs which prevent compiling using DotNet Core 3.1.301. Namely it looks like string and character literals are being mixed up, also the status string was not included in the class definition. Opening this issue so I can submit a pull request with a fix.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.