• Home
  • History
  • Annotate
Name Date Size #Lines LOC

..14-Oct-2019-

cmd/H14-Oct-2019-299244

README.mdH A D14-Oct-20197.4 KiB293216

config.goH A D14-Oct-20194.8 KiB152110

config_test.goH A D14-Oct-20195.6 KiB12794

devicetoken.goH A D14-Oct-20199.9 KiB270173

devicetoken_test.goH A D14-Oct-201910.9 KiB345268

go.modH A D14-Oct-2019371 1310

go.sumH A D14-Oct-20192.3 KiB2423

go_mod_tidy_hack.goH A D14-Oct-2019974 252

persist.goH A D14-Oct-20192.4 KiB7446

persist_test.goH A D14-Oct-20195 KiB172134

sender.goH A D14-Oct-20193.3 KiB9654

token.goH A D14-Oct-201937.2 KiB1,113840

token_test.goH A D14-Oct-201930 KiB1,035865

version.goH A D14-Oct-20191.2 KiB4624

README.md

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