Last active
September 8, 2017 14:30
-
-
Save Maarten88/9aacc25368601a2d65b417dc90945440 to your computer and use it in GitHub Desktop.
Microsoft Bot Framework Bot Authentication migrated to dotnet core 2.0
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using Microsoft.Bot.Connector; | |
namespace Microsoft.Extensions.DependencyInjection | |
{ | |
/// <summary> | |
/// Extension methods to add BotAuthentication capabilities to an HTTP application pipeline. | |
/// </summary> | |
public static class BotAuthenticationAppBuilderExtensions | |
{ | |
public static AuthenticationBuilder AddBotAuthentication(this AuthenticationBuilder builder, string authenticationScheme, string microsoftAppId, string microsoftAppPassword) | |
{ | |
if (builder == null) | |
{ | |
throw new ArgumentNullException(nameof(builder)); | |
} | |
if (authenticationScheme != "Bearer") | |
{ | |
throw new ArgumentNullException("AuthenticationScheme must be set to \"Bearer\""); | |
} | |
if (string.IsNullOrEmpty(microsoftAppId)) | |
{ | |
throw new ArgumentNullException(nameof(microsoftAppId)); | |
} | |
if (string.IsNullOrEmpty(microsoftAppPassword)) | |
{ | |
throw new ArgumentNullException(nameof(microsoftAppPassword)); | |
} | |
return builder | |
.AddScheme<BotAuthenticationSchemeOptions, BotAuthenticationHandler>(authenticationScheme, null, options => | |
{ | |
options.MicrosoftAppId = microsoftAppId; | |
options.MicrosoftAppPassword = microsoftAppPassword; | |
}); | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System.Security.Claims; | |
using System.Threading; | |
using System.Threading.Tasks; | |
using Microsoft.AspNetCore.Authentication; | |
using Microsoft.Extensions.Options; | |
using Microsoft.Extensions.Logging; | |
using System.Text.Encodings.Web; | |
namespace Microsoft.Bot.Connector | |
{ | |
/// <summary> | |
/// Bot authentication hanlder used by <see cref="BotAuthenticationHandler"/>. | |
/// </summary> | |
public sealed class BotAuthenticationHandler : AuthenticationHandler<BotAuthenticationSchemeOptions> | |
{ | |
public BotAuthenticationHandler(IOptionsMonitor<BotAuthenticationSchemeOptions> options, ILoggerFactory logger, UrlEncoder encoder, ISystemClock clock) : base(options, logger, encoder, clock) | |
{ | |
} | |
protected override async Task<AuthenticateResult> HandleAuthenticateAsync() | |
{ | |
if (await Options.CredentialProvider.IsAuthenticationDisabledAsync()) | |
{ | |
var principal = new ClaimsPrincipal(new ClaimsIdentity(new Claim[] { new Claim(ClaimTypes.Role, "Bot") })); | |
return AuthenticateResult.Success(new AuthenticationTicket(principal, new AuthenticationProperties(), BotAuthenticationSchemeOptions.AuthenticationScheme)); | |
} | |
string token = null; | |
string authorization = Request.Headers["Authorization"]; | |
token = authorization?.Substring("Bearer ".Length).Trim(); | |
// If no token found, no further work possible | |
// and Authentication is not disabled fail | |
if (string.IsNullOrEmpty(token)) | |
{ | |
return AuthenticateResult.Fail("No JwtToken is present and BotAuthentication is enabled!"); | |
} | |
var authenticator = new BotAuthenticator(Options.CredentialProvider, Options.OpenIdConfiguration, Options.DisableEmulatorTokens); | |
var identityToken = await authenticator.TryAuthenticateAsync(BotAuthenticationSchemeOptions.AuthenticationScheme, token, CancellationToken.None); | |
if (identityToken.Authenticated) | |
{ | |
identityToken.Identity.AddClaim(new Claim(ClaimTypes.Role, "Bot")); | |
var principal = new ClaimsPrincipal(identityToken.Identity); | |
var ticket = new AuthenticationTicket(principal, new AuthenticationProperties(), BotAuthenticationSchemeOptions.AuthenticationScheme); | |
Context.User = principal; | |
if (Options.SaveToken) | |
{ | |
ticket.Properties.StoreTokens(new[] | |
{ | |
new AuthenticationToken { Name = "access_token", Value = token } | |
}); | |
} | |
return AuthenticateResult.Success(ticket); | |
} | |
else | |
{ | |
return AuthenticateResult.Fail($"Failed to authenticate JwtToken {token}"); | |
} | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using Microsoft.AspNetCore.Authentication; | |
using System; | |
namespace Microsoft.Bot.Connector | |
{ | |
/// <summary> | |
/// Options for <see cref="BotAuthenticationSchemeOptions"/>. | |
/// </summary> | |
public sealed class BotAuthenticationSchemeOptions : AuthenticationSchemeOptions | |
{ | |
Lazy<ICredentialProvider> credentialProvider; | |
public BotAuthenticationSchemeOptions() : base() | |
{ | |
this.credentialProvider = new Lazy<ICredentialProvider>(() => new StaticCredentialProvider(this.MicrosoftAppId, this.MicrosoftAppPassword)); | |
} | |
public string MicrosoftAppId { get; set; } | |
public string MicrosoftAppPassword { get; set; } | |
/// <summary> | |
/// The <see cref="ICredentialProvider"/> used for authentication. | |
/// </summary> | |
public ICredentialProvider CredentialProvider | |
{ | |
get | |
{ | |
if (string.IsNullOrEmpty(this.MicrosoftAppId) || string.IsNullOrEmpty(this.MicrosoftAppId)) | |
{ | |
throw new ArgumentException("BotAuthenticationOptions: MicrosoftAppId and/or MicrosoftAppId missing"); | |
} | |
return this.credentialProvider.Value; | |
} | |
} | |
public const string AuthenticationScheme = "Bearer"; | |
/// <summary> | |
/// The OpenId configuation. | |
/// </summary> | |
public string OpenIdConfiguration { set; get; } = JwtConfig.ToBotFromChannelOpenIdMetadataUrl; | |
/// <summary> | |
/// Flag indicating if emulator tokens should be disabled. | |
/// </summary> | |
public bool DisableEmulatorTokens { set; get; } = false; | |
/// <summary> | |
/// Flag indicating if <see cref="BotAuthenticationHandler"/> should be stored in | |
/// the returned <see cref="Microsoft.AspNetCore.Authentication.AuthenticationTicket"/>. | |
/// </summary> | |
public bool SaveToken { set; get; } = true; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment