This repository contains a security microservice built using the ServiceBricks foundation. The security microservice is responsible for application security and user management built using the Microsoft ASP.NET Core Identity (v3) provider. It also stores auditing events for users.
The NuGet package ServiceBricks.Security.Member that allows any ServiceBricks hosted microservice application to become a security member using JWT tokens.
- Microsoft ASP.NET Core Identity (v3)
Install the NuGet package ServiceBricks.Security.Member to your web application and add the ServiceBricks:Security:Token application settings. If the settings match the security microservices application settings, it will be joined as a member of the platform using JWT bearer token membership.
Make sure to add the following line to startup.
services.AddServiceBricksSecurityMember(Configuration);
Audit user events.
public class AuditUserDto : DataTransferObject
{
public DateTimeOffset CreateDate { get; set; }
public string UserStorageKey { get; set; }
public string IPAddress { get; set; }
public string UserAgent { get; set; }
public string AuditName { get; set; }
public string Data { get; set; }
}
- DomainCreateDateRule - CreateDate property
Application user object.
public partial class ApplicationUserDto : DataTransferObject
{
/// <summary>
/// Gets or sets the user name for this user.
/// </summary>
public virtual string UserName { get; set; }
/// <summary>
/// Gets or sets the normalized user name for this user.
/// </summary>
public virtual string NormalizedUserName { get; set; }
/// <summary>
/// Gets or sets the email address for this user.
/// </summary>
public virtual string Email { get; set; }
/// <summary>
/// Gets or sets the normalized email address for this user.
/// </summary>
public virtual string NormalizedEmail { get; set; }
/// <summary>
/// Gets or sets a flag indicating if a user has confirmed their email address.
/// </summary>
/// <value>True if the email address has been confirmed, otherwise false.</value>
public virtual bool EmailConfirmed { get; set; }
/// <summary>
/// Gets or sets a salted and hashed representation of the password for this user.
/// </summary>
public virtual string PasswordHash { get; set; }
/// <summary>
/// A random value that must change whenever a users credentials change (password changed, login removed)
/// </summary>
public virtual string SecurityStamp { get; set; }
/// <summary>
/// A random value that must change whenever a user is persisted to the store
/// </summary>
public virtual string ConcurrencyStamp { get; set; } = Guid.NewGuid().ToString();
/// <summary>
/// Gets or sets a telephone number for the user.
/// </summary>
public virtual string PhoneNumber { get; set; }
/// <summary>
/// Gets or sets a flag indicating if a user has confirmed their telephone address.
/// </summary>
/// <value>True if the telephone number has been confirmed, otherwise false.</value>
public virtual bool PhoneNumberConfirmed { get; set; }
/// <summary>
/// Gets or sets a flag indicating if two factor authentication is enabled for this user.
/// </summary>
/// <value>True if 2fa is enabled, otherwise false.</value>
public virtual bool TwoFactorEnabled { get; set; }
/// <summary>
/// Gets or sets the date and time, in UTC, when any user lockout ends.
/// </summary>
/// <remarks>
/// A value in the past means the user is not locked out.
/// </remarks>
public virtual DateTimeOffset? LockoutEnd { get; set; }
/// <summary>
/// Gets or sets a flag indicating if the user could be locked out.
/// </summary>
/// <value>True if the user could be locked out, otherwise false.</value>
public virtual bool LockoutEnabled { get; set; }
/// <summary>
/// Gets or sets the number of failed login attempts for the current user.
/// </summary>
public virtual int AccessFailedCount { get; set; }
public virtual DateTimeOffset CreateDate { get; set; }
public virtual DateTimeOffset UpdateDate { get; set; }
}
- DomainCreateUpdateDateRule - CreateDate and UpdateDate property
Application role object.
public partial class ApplicationRoleDto : DataTransferObject
{
/// <summary>
/// Gets or sets the name for this role.
/// </summary>
public virtual string Name { get; set; }
/// <summary>
/// Gets or sets the normalized name for this role.
/// </summary>
public virtual string NormalizedName { get; set; }
/// <summary>
/// A random value that should change whenever a role is persisted to the store
/// </summary>
public virtual string ConcurrencyStamp { get; set; } = Guid.NewGuid().ToString();
}
None
Stores claims associated to an application role.
public partial class ApplicationRoleClaimDto : DataTransferObject
{
/// <summary>
/// Gets or sets the of the primary key of the role associated with this claim.
/// </summary>
public virtual string RoleStorageKey { get; set; }
/// <summary>
/// Gets or sets the claim type for this claim.
/// </summary>
public virtual string ClaimType { get; set; }
/// <summary>
/// Gets or sets the claim value for this claim.
/// </summary>
public virtual string ClaimValue { get; set; }
}
None
Stores relationship between an application user and application role.
public partial class ApplicationUserRoleDto : DataTransferObject
{
/// <summary>
/// Gets or sets the primary key of the user that is linked to a role.
/// </summary>
public virtual string UserStorageKey { get; set; }
/// <summary>
/// Gets or sets the primary key of the role that is linked to the user.
/// </summary>
public virtual string RoleStorageKey { get; set; }
}
None
Stores claims associated to an application user.
public partial class ApplicationUserClaimDto : DataTransferObject
{
/// <summary>
/// Gets or sets the primary key of the user associated with this claim.
/// </summary>
public virtual string UserStorageKey { get; set; }
/// <summary>
/// Gets or sets the claim type for this claim.
/// </summary>
public virtual string ClaimType { get; set; }
/// <summary>
/// Gets or sets the claim value for this claim.
/// </summary>
public virtual string ClaimValue { get; set; }
}
None
Stores logins associated to an application user.
public partial class ApplicationUserLoginDto : DataTransferObject
{
/// <summary>
/// Gets or sets the login provider for the login (e.g. facebook, google)
/// </summary>
public virtual string LoginProvider { get; set; }
/// <summary>
/// Gets or sets the unique provider identifier for this login.
/// </summary>
public virtual string ProviderKey { get; set; }
/// <summary>
/// Gets or sets the friendly name used in a UI for this login.
/// </summary>
public virtual string ProviderDisplayName { get; set; }
/// <summary>
/// Gets or sets the primary key of the user associated with this login.
/// </summary>
public virtual string UserStorageKey { get; set; }
}
None
Stores login tokens associated to an application user.
public partial class ApplicationUserTokenDto : DataTransferObject
{
/// <summary>
/// Gets or sets the primary key of the user that the token belongs to.
/// </summary>
public virtual string UserStorageKey { get; set; }
/// <summary>
/// Gets or sets the LoginProvider this token is from.
/// </summary>
public virtual string LoginProvider { get; set; }
/// <summary>
/// Gets or sets the name of the token.
/// </summary>
public virtual string Name { get; set; }
/// <summary>
/// Gets or sets the token value.
/// </summary>
public virtual string Value { get; set; }
}
None
None
None
This process is associated to the SendConfirmEmailRule Business Rule.
The business rule will first create an email and replace the callback url (with confirmation code) inside of the text. It will then send a service bus broadcast message for CreateApplicationEmail. The notification microservice will store this message and it will be sent when it is processed on a background task using a timer.
public class SendConfirmEmailProcess : DomainProcess
{
public SendConfirmEmailProcess(ApplicationUserDto applicationUser, string callbackUrl)
{
ApplicationUser = applicationUser;
CallbackUrl = callbackUrl;
}
public ApplicationUserDto ApplicationUser { get; set; }
public string CallbackUrl { get; set; }
}
This process is associated to the SendResetPasswordEmailRule Business Rule.
The business rule will first create an email and replace the callback url (with confirmation code) inside of the Reset Email text. It will then send a service bus broadcast message for CreateApplicationEmail. The notification microservice will store this message and it will be sent when it is processed on a background task using a timer.
public class SendResetPasswordEmailProcess : DomainProcess
{
public SendResetPasswordEmailProcess(ApplicationUserDto applicationUser, string callbackUrl)
{
ApplicationUser = applicationUser;
CallbackUrl = callbackUrl;
}
public ApplicationUserDto ApplicationUser { get; set; }
public string CallbackUrl { get; set; }
}
This process is associated to the UserConfirmEmailRule Business Rule.
The business rule will validate a confirmation code with a user.
public class UserConfirmEmailProcess : DomainProcess
{
public UserConfirmEmailProcess(string userStorageKey, string code)
{
UserStorageKey = userStorageKey;
Code = code;
}
public string UserStorageKey { get; set; }
public string Code { get; set; }
}
This process is associated to the UserForgotPasswordRule Business Rule.
The business rule will create a reset token for a user, replace the callback url (with reset code) inside of the Forgot Password email text. It will then send a service bus broadcast message for CreateApplicationEmail. The notification microservice will store this message and it will be sent when it is processed on a background task using a timer.
public class UserForgotPasswordProcess : DomainProcess<string>
{
public UserForgotPasswordProcess(string userStorageKey)
{
DomainObject = userStorageKey;
}
}
This process is associated to the UserInvalidPasswordRule Business Rule.
The business rule will create an audit message for the user denoting an invalid password login request.
public class UserInvalidPasswordProcess : DomainProcess
{
public UserInvalidPasswordProcess(string userStorageKey, string email)
{
UserStorageKey = userStorageKey;
Email = email;
}
public string Email { get; set; }
public string UserStorageKey { get; set; }
}
This process is associated to the UserLoginRule Business Rule.
The business rule will attempt to signin a user and create an audituser message.
public class UserLoginProcess : DomainProcess
{
public UserLoginProcess(
string email,
string password,
bool rememberMe)
{
Email = email;
Password = password;
RememberMe = rememberMe;
}
public string Email { get; set; }
public string Password { get; set; }
public bool RememberMe { get; set; }
public ApplicationSigninResult ApplicationSigninResult { get; set; }
}
This process is associated to the UserLogoutRule Business Rule.
The business rule will logout a user and create an audituser message.
public class UserLogoutProcess : DomainProcess
{
public UserLogoutProcess(string userStorageKey)
{
UserStorageKey = userStorageKey;
}
public string UserStorageKey { get; set; }
}
This process is associated to the UserMFARule Business Rule.
The business rule will send the mult-factor authentication code to the user.
public class UserMfaProcess : DomainProcess
{
public UserMfaProcess(string selectedProvider)
{
SelectedProvider = selectedProvider;
}
public string SelectedProvider { get; set; }
}
This process is associated to the UserPasswordChangeRule Business Rule.
The business rule will send attempt to change a user's password.
public class UserPasswordChangeProcess : DomainProcess
{
public UserPasswordChangeProcess(string userStorageKey, string oldPassword, string newPassword)
{
UserStorageKey = userStorageKey;
OldPassword = oldPassword;
NewPassword = newPassword;
}
public string UserStorageKey { get; set; }
public string OldPassword { get; set; }
public string NewPassword { get; set; }
}
This process is associated to the UserPasswordResetRule Business Rule.
The business rule will attempt to reset a user's password with the reset token.
public class UserPasswordResetProcess : DomainProcess
{
public UserPasswordResetProcess(string email, string password, string code)
{
Email = email;
Password = password;
Code = code;
}
public string Email { get; set; }
public string Password { get; set; }
public string Code { get; set; }
}
This process is associated to the UserProfileChangeRule Business Rule.
The business rule will attempt to update a user's profile.
public class UserProfileChangeProcess : DomainProcess
{
public UserProfileChangeProcess(string userStorageKey)
{
UserStorageKey = userStorageKey;
}
public string UserStorageKey { get; set; }
}
This process is associated to the UserRegisterAdminRule Business Rule.
The business rule will attempt to regiser a user as an admin user.
public class UserRegisterAdminProcess : UserRegisterProcess
{
public UserRegisterAdminProcess(
string email,
string password) : base(email, password)
{
}
}
This process is associated to the UserRegisterRule Business Rule.
The business rule will attempt to regiser a user.
public class UserRegisterProcess : DomainProcess
{
public UserRegisterProcess(
string email,
string password,
bool createEmail = true,
bool emailConfirmed = false)
{
Email = email;
Password = password;
CreateEmail = createEmail;
EmailConfirmed = emailConfirmed;
}
public string Email { get; set; }
public string Password { get; set; }
public bool CreateEmail { get; set; }
public bool EmailConfirmed { get; set; }
}
This process is associated to the UserResendConfirmationProcessRule Business Rule.
The business rule will send the user another email with a confirmation code.
public class UserResendConfirmationProcess : DomainProcess
{
public UserResendConfirmationProcess(string userStorageKey)
{
UserStorageKey = userStorageKey;
}
public string UserStorageKey { get; set; }
}
No Broadcast Messages
- This microservice sends CreateApplicationEmailBroadcast messages to the service bus.
{
// ServiceBricks Settings
"ServiceBricks":{
// Security Microservice Settings
"Security": {
// The callback url of the server if linkgenerator is not available
"CallbackUrl": "https://localhost:7000",
// JWT token settings
"Token": {
"ValidIssuer": "https://localhost:7000",
"ValidAudience": "ServiceBricks",
"ExpireMinutes": 1440,
// Change this key in production!
"SecretKey": "1111111111111111111111111111111111111111111111111111111111111111"
}
},
}
}
ServiceBricks is the cornerstone for building a microservices foundation. Visit http://ServiceBricks.com to learn more.