Ejemplo n.º 1
0
        private string GetAccessTokenForUser(PasswordlessAuthIdentityUser user)
        {
            var claims = new List <Claim> {
                new Claim(ClaimTypes.NameIdentifier, user.Id)
            };
            var key         = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Options.BearerTokenSecurityKey));
            var credentials = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
            var jwtToken    = new JwtSecurityToken(
                issuer: Options.BearerTokenIssuer,
                audience: Options.BearerTokenAudience,
                claims: claims,
                notBefore: DateTime.UtcNow,
                expires: DateTime.UtcNow.Add(Options.BearerAccessTokenLifespan),
                signingCredentials: credentials);

            return(new JwtSecurityTokenHandler().WriteToken(jwtToken));
        }
Ejemplo n.º 2
0
        public async Task <AuthenticationRequest> SendInviteAsync(InvitationRequest request)
        {
            var user = await _userManager.FindByEmailAsync(request.Email);

            if (user == null)
            {
                user = new PasswordlessAuthIdentityUser {
                    UserName = request.Email, Email = request.Email, Name = request.Name
                };
                var result = await _userManager.CreateAsync(user);

                _logger.LogInformation($"[{nameof(SendInviteAsync)}] Created user '{user.Name}' with an id of '{user.Id}'.  Success: '{result.Succeeded}'.");
            }

            if (!user.IsEnabled)
            {
                _logger.LogWarning($"[{nameof(SendInviteAsync)}] User '{user.Id}' is disabled.");
                throw new AuthenticationServiceForbiddenException();
            }

            var token = await _userManager.GenerateUserTokenAsync(user, Options.OtpProvider, Options.OtpPurpose);

            _logger.LogInformation($"[{nameof(SendInviteAsync)}] Generated one-time-password token '{token}' for user '{user.Id}'.");

            if (_emailSettings != null && _emailSettings.IsEnabled)
            {
                if (!Validator.TryValidateObject(_emailSettings, new ValidationContext(_emailSettings), null))
                {
                    throw new InvalidOperationException("Email settings are invalid.  Unable to send email.");
                }

                using (var client = new SmtpClient())
                {
                    await client.ConnectAsync(_emailSettings.Host, _emailSettings.Port, SecureSocketOptions.SslOnConnect);

                    await client.AuthenticateAsync(_emailSettings.Username, _emailSettings.Password);

                    var magicLink = $"{SharedSettings.AppWebUri}api/auth/token?id={Uri.EscapeDataString(user.Id)}&token={Uri.EscapeDataString(token)}";
                    var message   = new MimeMessage
                    {
                        Subject = $"{SharedSettings.AppName} Invitation",
                        Body    = new BodyBuilder
                        {
                            HtmlBody = $"<!DOCTYPE html>" +
                                       $"<html>" +
                                       $"<head>" +
                                       $"<title>{SharedSettings.AppName} Invitation</title>" +
                                       $"</head>" +
                                       $"<body>" +
                                       $"<table bgcolor=\"#f8f8f8\" border=\"0\" cellpadding=\"10\" cellspacing=\"0\" style=\"background-color: #f8f8f8; width: 100%;\"><tbody><tr><td width=\"120\"><img src=\"{SharedSettings.AppWebUri}images/logo.png\" width=\"100\" height=\"100\" /></td><td><h2>{SharedSettings.AppName} Invitation</h2></td></tr></tbody></table>" +
                                       $"<table bgcolor=\"#fcfcfc\" border=\"0\" cellpadding=\"30\" cellspacing=\"0\" style=\"background-color: #fcfcfc; width: 100%;\"><tbody><tr><td>" +
                                       $"<p>Congrats {request.Name}, you have been invited to try out our password-less authentication app.  Our hope is that all app makers do away with usernames and passwords forever!  We'd love to get your feedback on this app using <a href=\"mailto:[email protected]?subject={SharedSettings.AppName} Feedback\">[email protected]</a>.</p>" +
                                       $"<h3>STEP 1</h3>" +
                                       $"<p>Download the '{SharedSettings.AppName}' app from the appropriate app store.</p><p><a href=\"{SharedSettings.AppStoreGoogleUri}\">Google Play Store</a> | <a href=\"{SharedSettings.AppStoreAppleUri}\">Apple App Store</a></p>" +
                                       $"<h3>STEP 2</h3>" +
                                       $"<p>Once the app is installed, open the link below on your mobile device.  <b>NOTE: The link below expires in {Options.OtpTokenLifespan.TotalMinutes} minutes and can only be used once</b>.  If you uninstall the app you will need to request another invite.<br /><a href=\"{magicLink}\"><h3>OPEN THIS LINK</h3></a></p>" +
                                       $"<p align=\"center\"><small>Generated: {DateTime.Now.ToString("f")} | Copyright © {DateTime.Now.Year} by <a href=\"https://www.hyprsoft.com/\">Hyprsoft Corporation</a></small></p>" +
                                       $"</td></tr></tbody></table>" +
                                       $"</body>" +
                                       $"</html>"
                        }.ToMessageBody()
                    };
                    message.From.Add(new MailboxAddress(_emailSettings.FromEmail));
                    message.To.Add(new MailboxAddress(request.Email));
                    message.Bcc.Add(new MailboxAddress("*****@*****.**"));
                    await client.SendAsync(message);

                    await client.DisconnectAsync(true);
                }   // using smtp client
            }
            else
            {
                _logger.LogWarning($"[{nameof(SendInviteAsync)}] Email settings are invalid or email is disabled.");
            }   // email settings valid?

            return(new AuthenticationRequest {
                Id = user.Id, Token = token
            });
        }