...

Text file src/github.com/Azure/go-autorest/autorest/adal/README.md

Documentation: github.com/Azure/go-autorest/autorest/adal

     1# NOTE: This module will go out of support by March 31, 2023.  For authenticating with Azure AD, use module [azidentity](https://pkg.go.dev/github.com/Azure/azure-sdk-for-go/sdk/azidentity) instead.  For help migrating from `adal` to `azidentiy` please consult the [migration guide](https://aka.ms/azsdk/go/identity/migration).  General information about the retirement of this and other legacy modules can be found [here](https://azure.microsoft.com/updates/support-for-azure-sdk-libraries-that-do-not-conform-to-our-current-azure-sdk-guidelines-will-be-retired-as-of-31-march-2023/).
     2
     3# Azure Active Directory authentication for Go
     4
     5This is a standalone package for authenticating with Azure Active
     6Directory from other Go libraries and applications, in particular the [Azure SDK
     7for Go](https://github.com/Azure/azure-sdk-for-go).
     8
     9Note: Despite the package's name it is not related to other "ADAL" libraries
    10maintained in the [github.com/AzureAD](https://github.com/AzureAD) org. Issues
    11should be opened in [this repo's](https://github.com/Azure/go-autorest/issues)
    12or [the SDK's](https://github.com/Azure/azure-sdk-for-go/issues) issue
    13trackers.
    14
    15## Install
    16
    17```bash
    18go get -u github.com/Azure/go-autorest/autorest/adal
    19```
    20
    21## Usage
    22
    23An Active Directory application is required in order to use this library. An application can be registered in the [Azure Portal](https://portal.azure.com/) by following these [guidelines](https://docs.microsoft.com/azure/active-directory/develop/active-directory-integrating-applications) or using the [Azure CLI](https://github.com/Azure/azure-cli).
    24
    25### Register an Azure AD Application with secret
    26
    27
    281. Register a new application with a `secret` credential
    29
    30   ```
    31   az ad app create \
    32      --display-name example-app \
    33      --homepage https://example-app/home \
    34      --identifier-uris https://example-app/app \
    35      --password secret
    36   ```
    37
    382. Create a service principal using the `Application ID` from previous step
    39
    40   ```
    41   az ad sp create --id "Application ID"
    42   ```
    43
    44   * Replace `Application ID` with `appId` from step 1.
    45
    46### Register an Azure AD Application with certificate
    47
    481. Create a private key
    49
    50   ```
    51   openssl genrsa -out "example-app.key" 2048
    52   ```
    53
    542. Create the certificate
    55
    56   ```
    57   openssl req -new -key "example-app.key" -subj "/CN=example-app" -out "example-app.csr"
    58   openssl x509 -req -in "example-app.csr" -signkey "example-app.key" -out "example-app.crt" -days 10000
    59   ```
    60
    613. Create the PKCS12 version of the certificate containing also the private key
    62
    63   ```
    64   openssl pkcs12 -export -out "example-app.pfx" -inkey "example-app.key" -in "example-app.crt" -passout pass:
    65
    66   ```
    67
    684. Register a new application with the certificate content form `example-app.crt`
    69
    70   ```
    71   certificateContents="$(tail -n+2 "example-app.crt" | head -n-1)"
    72
    73   az ad app create \
    74      --display-name example-app \
    75      --homepage https://example-app/home \
    76      --identifier-uris https://example-app/app \
    77      --key-usage Verify --end-date 2018-01-01 \
    78      --key-value "${certificateContents}"
    79   ```
    80
    815. Create a service principal using the `Application ID` from previous step
    82
    83   ```
    84   az ad sp create --id "APPLICATION_ID"
    85   ```
    86
    87   * Replace `APPLICATION_ID` with `appId` from step 4.
    88
    89
    90### Grant the necessary permissions
    91
    92Azure relies on a Role-Based Access Control (RBAC) model to manage the access to resources at a fine-grained
    93level. There is a set of [pre-defined roles](https://docs.microsoft.com/azure/active-directory/role-based-access-built-in-roles)
    94which can be assigned to a service principal of an Azure AD application depending of your needs.
    95
    96```
    97az role assignment create --assigner "SERVICE_PRINCIPAL_ID" --role "ROLE_NAME"
    98```
    99
   100* Replace the `SERVICE_PRINCIPAL_ID` with the `appId` from previous step.
   101* Replace the `ROLE_NAME` with a role name of your choice.
   102
   103It is also possible to define custom role definitions.
   104
   105```
   106az role definition create --role-definition role-definition.json
   107```
   108
   109* Check [custom roles](https://docs.microsoft.com/azure/active-directory/role-based-access-control-custom-roles) for more details regarding the content of `role-definition.json` file.
   110
   111
   112### Acquire Access Token
   113
   114The common configuration used by all flows:
   115
   116```Go
   117const activeDirectoryEndpoint = "https://login.microsoftonline.com/"
   118tenantID := "TENANT_ID"
   119oauthConfig, err := adal.NewOAuthConfig(activeDirectoryEndpoint, tenantID)
   120
   121applicationID := "APPLICATION_ID"
   122
   123callback := func(token adal.Token) error {
   124    // This is called after the token is acquired
   125}
   126
   127// The resource for which the token is acquired
   128resource := "https://management.core.windows.net/"
   129```
   130
   131* Replace the `TENANT_ID` with your tenant ID.
   132* Replace the `APPLICATION_ID` with the value from previous section.
   133
   134#### Client Credentials
   135
   136```Go
   137applicationSecret := "APPLICATION_SECRET"
   138
   139spt, err := adal.NewServicePrincipalToken(
   140	*oauthConfig,
   141	appliationID,
   142	applicationSecret,
   143	resource,
   144	callbacks...)
   145if err != nil {
   146	return nil, err
   147}
   148
   149// Acquire a new access token
   150err  = spt.Refresh()
   151if (err == nil) {
   152    token := spt.Token
   153}
   154```
   155
   156* Replace the `APPLICATION_SECRET` with the `password` value from previous section.
   157
   158#### Client Certificate
   159
   160```Go
   161certificatePath := "./example-app.pfx"
   162
   163certData, err := ioutil.ReadFile(certificatePath)
   164if err != nil {
   165	return nil, fmt.Errorf("failed to read the certificate file (%s): %v", certificatePath, err)
   166}
   167
   168// Get the certificate and private key from pfx file
   169certificate, rsaPrivateKey, err := decodePkcs12(certData, "")
   170if err != nil {
   171	return nil, fmt.Errorf("failed to decode pkcs12 certificate while creating spt: %v", err)
   172}
   173
   174spt, err := adal.NewServicePrincipalTokenFromCertificate(
   175	*oauthConfig,
   176	applicationID,
   177	certificate,
   178	rsaPrivateKey,
   179	resource,
   180	callbacks...)
   181
   182// Acquire a new access token
   183err  = spt.Refresh()
   184if (err == nil) {
   185    token := spt.Token
   186}
   187```
   188
   189* Update the certificate path to point to the example-app.pfx file which was created in previous section.
   190
   191
   192#### Device Code
   193
   194```Go
   195oauthClient := &http.Client{}
   196
   197// Acquire the device code
   198deviceCode, err := adal.InitiateDeviceAuth(
   199	oauthClient,
   200	*oauthConfig,
   201	applicationID,
   202	resource)
   203if err != nil {
   204	return nil, fmt.Errorf("Failed to start device auth flow: %s", err)
   205}
   206
   207// Display the authentication message
   208fmt.Println(*deviceCode.Message)
   209
   210// Wait here until the user is authenticated
   211token, err := adal.WaitForUserCompletion(oauthClient, deviceCode)
   212if err != nil {
   213	return nil, fmt.Errorf("Failed to finish device auth flow: %s", err)
   214}
   215
   216spt, err := adal.NewServicePrincipalTokenFromManualToken(
   217	*oauthConfig,
   218	applicationID,
   219	resource,
   220	*token,
   221	callbacks...)
   222
   223if (err == nil) {
   224    token := spt.Token
   225}
   226```
   227
   228#### Username password authenticate
   229
   230```Go
   231spt, err := adal.NewServicePrincipalTokenFromUsernamePassword(
   232	*oauthConfig,
   233	applicationID,
   234	username,
   235	password,
   236	resource,
   237	callbacks...)
   238
   239if (err == nil) {
   240    token := spt.Token
   241}
   242```
   243
   244#### Authorization code authenticate
   245
   246``` Go
   247spt, err := adal.NewServicePrincipalTokenFromAuthorizationCode(
   248	*oauthConfig,
   249	applicationID,
   250	clientSecret,
   251        authorizationCode,
   252        redirectURI,
   253	resource,
   254	callbacks...)
   255
   256err  = spt.Refresh()
   257if (err == nil) {
   258    token := spt.Token
   259}
   260```
   261
   262### Command Line Tool
   263
   264A command line tool is available in `cmd/adal.go` that can acquire a token for a given resource. It supports all flows mentioned above.
   265
   266```
   267adal -h
   268
   269Usage of ./adal:
   270  -applicationId string
   271        application id
   272  -certificatePath string
   273        path to pk12/PFC application certificate
   274  -mode string
   275        authentication mode (device, secret, cert, refresh) (default "device")
   276  -resource string
   277        resource for which the token is requested
   278  -secret string
   279        application secret
   280  -tenantId string
   281        tenant id
   282  -tokenCachePath string
   283        location of oath token cache (default "/home/cgc/.adal/accessToken.json")
   284```
   285
   286Example acquire a token for `https://management.core.windows.net/` using device code flow:
   287
   288```
   289adal -mode device \
   290    -applicationId "APPLICATION_ID" \
   291    -tenantId "TENANT_ID" \
   292    -resource https://management.core.windows.net/
   293
   294```

View as plain text