155 lines
6.8 KiB
C#
155 lines
6.8 KiB
C#
/*
|
|
*
|
|
* Copyright (c) Microsoft Corporation.
|
|
* All rights reserved.
|
|
*
|
|
* This code is licensed under the MIT License.
|
|
*
|
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
* of this software and associated documentation files(the "Software"), to deal
|
|
* in the Software without restriction, including without limitation the rights
|
|
* to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
|
|
* copies of the Software, and to permit persons to whom the Software is
|
|
* furnished to do so, subject to the following conditions :
|
|
*
|
|
* The above copyright notice and this permission notice shall be included in
|
|
* all copies or substantial portions of the Software.
|
|
*
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
|
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
* THE SOFTWARE.
|
|
*
|
|
*/
|
|
|
|
using System;
|
|
using System.Configuration;
|
|
using Microsoft.InformationProtection;
|
|
using Microsoft.Identity.Client;
|
|
using System.Security.Cryptography.X509Certificates;
|
|
using System.Linq;
|
|
using static BSOneMip.Define;
|
|
|
|
|
|
namespace BSOneMip
|
|
{
|
|
public class AuthDelegateImplementation : IAuthDelegate
|
|
{
|
|
// Set the redirect URI from the AAD Application Registration.
|
|
private static readonly string redirectUri = REDIRECT_URL; // ConfigurationManager.AppSettings["ida:RedirectUri"];
|
|
|
|
// Fetch cert thumbprint, appkey, and DoCertAuth flag from app.config
|
|
private static readonly string certThumb = APPSECU_ID; // ConfigurationManager.AppSettings["ida:CertThumbprint"];
|
|
private static readonly bool doCertAuth = false; // Convert.ToBoolean(ConfigurationManager.AppSettings["ida:DoCertAuth"]);
|
|
private static readonly string clientSecret = APPSECU_VAL; // ConfigurationManager.AppSettings["ida:ClientSecret"];
|
|
|
|
|
|
// Fetch tenant name from app.config
|
|
// We use the tenant ID to append to the authority, as we need this as a hint to find the correct tenant.
|
|
// Using the common endpoint without tenant throws an exception.
|
|
private static readonly string tenant = TENANT_ID; // ConfigurationManager.AppSettings["ida:Tenant"];
|
|
|
|
private ApplicationInfo appInfo;
|
|
//private TokenCache tokenCache = new TokenCache();
|
|
|
|
public AuthDelegateImplementation(ApplicationInfo appInfo)
|
|
{
|
|
this.appInfo = appInfo;
|
|
}
|
|
|
|
/// <summary>
|
|
/// AcquireToken is called by the SDK when auth is required for an operation.
|
|
/// Adding or loading an IFileEngine is typically where this will occur first.
|
|
/// The SDK provides all three parameters below.Identity from the EngineSettings.
|
|
/// Authority and resource are provided from the 401 challenge.
|
|
/// The SDK cares only that an OAuth2 token is returned.How it's fetched isn't important.
|
|
/// In this sample, we fetch the token using Active Directory Authentication Library(ADAL).
|
|
/// </summary>
|
|
/// <param name="identity"></param>
|
|
/// <param name="authority"></param>
|
|
/// <param name="resource"></param>
|
|
/// <returns>The OAuth2 token for the user</returns>
|
|
public string AcquireToken(Identity identity, string authority, string resource, string claim)
|
|
{
|
|
string sResult = "";
|
|
try
|
|
{
|
|
// Append tenant to authority and remove common.
|
|
if (authority.ToLower().Contains("common"))
|
|
{
|
|
var authorityUri = new Uri(authority);
|
|
authority = String.Format("https://{0}/{1}", authorityUri.Host, tenant);
|
|
}
|
|
|
|
IConfidentialClientApplication app;
|
|
|
|
if (doCertAuth)
|
|
{
|
|
//Console.WriteLine("Performing certificate based auth with {0}", certThumb);
|
|
Console.WriteLine("Performing certificate based auth with {0}", certThumb);
|
|
|
|
// Read cert from local machine
|
|
var certificate = ReadCertificateFromStore(certThumb);
|
|
// Use cert to build ClientAssertionCertificate
|
|
app = ConfidentialClientApplicationBuilder.Create(appInfo.ApplicationId)
|
|
.WithCertificate(certificate)
|
|
.WithRedirectUri(redirectUri)
|
|
.Build();
|
|
}
|
|
|
|
else
|
|
{
|
|
//Console.WriteLine("Performing client secret based auth.");
|
|
//Console.WriteLine("[BSOne] AIP 클라이언트 암호 기반 인증 .. 성공");
|
|
app = ConfidentialClientApplicationBuilder.Create(appInfo.ApplicationId)
|
|
.WithClientSecret(clientSecret)
|
|
.WithRedirectUri(redirectUri)
|
|
.Build();
|
|
|
|
}
|
|
|
|
string[] scopes = new string[] { resource[resource.Length - 1].Equals('/') ? $"{resource}.default" : $"{resource}/.default" };
|
|
|
|
AuthenticationResult authResult = app.AcquireTokenForClient(scopes)
|
|
.WithAuthority(authority)
|
|
.ExecuteAsync()
|
|
.GetAwaiter()
|
|
.GetResult();
|
|
// Return the token. The token is sent to the resource.
|
|
sResult = authResult.AccessToken;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//Console.WriteLine("[BSOne] AIP 클라이언트 암호 기반 인증 .. 실패");
|
|
Console.WriteLine("Fail .. AcquireToken() .. " + ex.Message);
|
|
}
|
|
return sResult;
|
|
}
|
|
|
|
private static X509Certificate2 ReadCertificateFromStore(string thumbprint)
|
|
{
|
|
X509Certificate2 cert = null;
|
|
X509Store store = new X509Store(StoreName.My, StoreLocation.CurrentUser);
|
|
store.Open(OpenFlags.ReadOnly);
|
|
X509Certificate2Collection certCollection = store.Certificates;
|
|
|
|
// Find unexpired certificates.
|
|
X509Certificate2Collection currentCerts = certCollection.Find(X509FindType.FindByTimeValid, DateTime.Now, false);
|
|
|
|
// From the collection of unexpired certificates, find the ones with the correct name.
|
|
X509Certificate2Collection signingCert = currentCerts.Find(X509FindType.FindByThumbprint, thumbprint, false);
|
|
|
|
// Return the first certificate in the collection, has the right name and is current.
|
|
cert = signingCert.OfType<X509Certificate2>().OrderByDescending(c => c.NotBefore).FirstOrDefault();
|
|
store.Close();
|
|
return cert;
|
|
}
|
|
|
|
|
|
|
|
}
|
|
}
|