using System; namespace HelloExtensions.Auth.Interfaces { public interface ICredentialUser { Guid? UserId { get; } } }
namespace HelloExtensions.Auth.Interfaces { public interface ICredentialToken { byte[] Token { get; } } }
namespace HelloExtensions.Auth.Interfaces { public interface ICredentialInfo : ICredentialUser, ICredentialToken { } }
namespace HelloExtensions.Auth.Interfaces { public interface IEncryptionKey { byte[] EncryptionKey { get; } } }
namespace HelloExtensions.Auth.Interfaces { public interface ICredentialInfoEx : ICredentialInfo, IEncryptionKey { } }
namespace HelloExtensions.Auth { public static class TokenValidator { private static class TokenParams { public const int TokenHeaderSize = 8; public const int MinTokenSize = TokenHeaderSize + 32; public const int MaxTokenSize = TokenHeaderSize + 256; } private static int GetTokenBodySize(byte[] token) { int bodySize = 0; for (int i = 0; i < 2; i++) bodySize |= token[i] << i * 8; return bodySize; } private static bool IsValidTokenInternal(byte[] token) { if (GetTokenBodySize(token) != token.Length - TokenParams.TokenHeaderSize) return false; // TODO: Additional Token Validation, // for ex., searching token in a Session Cache Manager return true; } public static bool IsValidToken(byte[] token) => token != null && token.Length >= TokenParams.MinTokenSize && token.Length <= TokenParams.MaxTokenSize && IsValidTokenInternal(token); } }
using System; namespace HelloExtensions.Auth { public static class IdentifierValidator { // TODO: check id exists in database private static bool IsIdentidierExists(Guid id) => true; public static bool IsValidIdentifier(Guid id) => id != Guid.Empty && IsIdentidierExists(id); public static bool IsValidIdentifier(Guid? id) => id.HasValue && IsValidIdentifier(id.Value); } }
namespace HelloExtensions.Auth { public enum KeySize : int { KeySize256 = 32, KeySize512 = 64, KeySize1024 = 128 } }
using System.Collections.Generic; using System.Collections.ObjectModel; namespace HelloExtensions.Auth { public static class KeySizes { public static IReadOnlyList<KeySize> Items { get; } static KeySizes() { Items = new ReadOnlyCollection<KeySize>( (KeySize[])typeof(KeySize).GetEnumValues() ); } } }
using System.Linq; namespace HelloExtensions.Auth { public static class KeyValidator { private static bool IsValidKeyInternal(byte[] key) { if (key.All(item => item == byte.MinValue)) return false; if (key.All(item => item == byte.MaxValue)) return false; // TODO: Additional Key Validation, for ex., checking for known testings values return true; } public static bool IsValidKey(byte[] key) => key != null && key.Length > 0 && KeySizes.Items.Contains((KeySize)key.Length) && IsValidKeyInternal(key); } }
namespace HelloExtensions.Auth { using Interfaces; public static class CredentialsExtensions { public static bool IsValid(this ICredentialUser user) => IdentifierValidator.IsValidIdentifier(user.UserId); public static bool IsValid(this ICredentialToken token) => TokenValidator.IsValidToken(token.Token); public static bool IsValid(this ICredentialInfo info) => ((ICredentialUser)info).IsValid() && ((ICredentialToken)info).IsValid(); public static bool IsValid(this ICredentialInfoEx info) => ((ICredentialInfo)info).IsValid(); public static bool IsValidEx(this ICredentialInfoEx info) => ((ICredentialInfo)info).IsValid() && KeyValidator.IsValidKey(info.EncryptionKey); } }
namespace HelloExtensions.Auth.Interfaces { public interface IAuthCredentials { } }
using System; namespace HelloExtensions.Auth.Interfaces { public interface ICredentialUser : IAuthCredentials { Guid? UserId { get; } } }
namespace HelloExtensions.Auth.Interfaces { public interface ICredentialToken : IAuthCredentials { byte[] Token { get; } } }
using System; namespace HelloExtensions.Auth { using Interfaces; public static class CredentialsExtensions { private static bool IsValid(this ICredentialUser user) => IdentifierValidator.IsValidIdentifier(user.UserId); private static bool IsValid(this ICredentialToken token) => TokenValidator.IsValidToken(token.Token); private static bool IsValid(this ICredentialInfo info) => ((ICredentialUser)info).IsValid() && ((ICredentialToken)info).IsValid(); private static bool IsValid(this ICredentialInfoEx info) => ((ICredentialInfo)info).IsValid() && KeyValidator.IsValidKey(info.EncryptionKey); public static bool IsValid(this IAuthCredentials credentials) { if (credentials == null) { //throw new ArgumentNullException(nameof(credentials)); return false; } { var credentialInfoEx = credentials as ICredentialInfoEx; if (credentialInfoEx != null) return credentialInfoEx.IsValid(); } { var credentialInfo = credentials as ICredentialInfo; if (credentialInfo != null) return credentialInfo.IsValid(); } { var credentialUser = credentials as ICredentialUser; if (credentialUser != null) return credentialUser.IsValid(); } { var credentialToken = credentials as ICredentialToken; if (credentialToken != null) return credentialToken.IsValid(); } //throw new ArgumentException( // FormattableString.Invariant( // $"Specified {nameof(IAuthCredentials)} implementation not supported." // ), // nameof(credentials) //); return false; } } }
namespace HelloExtensions.ProjectA.Auth.Interfaces { public interface IXmlSupport { void LoadFromXml(string xml); string SaveToXml(); } }
using HelloExtensions.Auth.Interfaces; namespace HelloExtensions.ProjectA.Auth.Interfaces { public interface IUserCredentials : ICredentialInfo, IXmlSupport { } }
using HelloExtensions.Auth.Interfaces; namespace HelloExtensions.ProjectA.Auth.Interfaces { public interface IUserCredentialsEx : ICredentialInfoEx, IXmlSupport { } }
using System; using HelloExtensions.Auth.Interfaces; namespace HelloExtensions.ProjectA.Auth.Entities { using Interfaces; public class UserCredentials : IUserCredentials { public Guid? UserId { get; set; } public byte[] SessionToken { get; set; } byte[] ICredentialToken.Token => this.SessionToken; public virtual void LoadFromXml(string xml) { // TODO: Implement loading from XML throw new NotImplementedException(); } public virtual string SaveToXml() { // TODO: Implement saving to XML throw new NotImplementedException(); } } }
using System; namespace HelloExtensions.ProjectA.Auth.Entities { using Interfaces; public class UserCredentialsEx : UserCredentials, IUserCredentialsEx { public byte[] EncryptionKey { get; set; } public override void LoadFromXml(string xml) { // TODO: Implement loading from XML throw new NotImplementedException(); } public override string SaveToXml() { // TODO: Implement saving to XML throw new NotImplementedException(); } } }
namespace HelloExtensions.ProjectA.Auth { using Interfaces; public interface IAuthProvider { IUserCredentials AuthorizeUser(string login, string password); IUserCredentialsEx AuthorizeUserEx(string login, string password); } }
namespace HelloExtensions.ProjectA.Auth { using Entities; using Interfaces; internal sealed class AuthProvider : IAuthProvider { // TODO: Implement User Authorization public IUserCredentials AuthorizeUser(string login, string password) => new UserCredentials(); // TODO: Implement User Authorization public IUserCredentialsEx AuthorizeUserEx(string login, string password) => new UserCredentialsEx(); } }
using System; namespace HelloExtensions.ProjectA.Auth { public static class AuthProviderFactory { private static readonly Lazy<IAuthProvider> defaultInstance; static AuthProviderFactory() { defaultInstance = new Lazy<IAuthProvider>(Create); } public static IAuthProvider Create() => new AuthProvider(); public static IAuthProvider Default => defaultInstance.Value; } }
namespace HelloExtensions.ProjectB.Auth.Interfaces { public interface IJsonSupport { void LoadFromJson(string json); string SaveToJson(); } }
using HelloExtensions.Auth.Interfaces; namespace HelloExtensions.ProjectB.Auth.Interfaces { public interface ISimpleUserCredentials : ICredentialUser, IJsonSupport { } }
using HelloExtensions.Auth.Interfaces; namespace HelloExtensions.ProjectB.Auth.Interfaces { public interface IUserCredentials : ICredentialInfo, IJsonSupport { } }
using HelloExtensions.Auth.Interfaces; namespace HelloExtensions.ProjectB.Auth.Interfaces { public interface INonRegistrationSessionCredentials : ICredentialToken, IJsonSupport { } }
using System; namespace HelloExtensions.ProjectB.Auth.Entities { using Interfaces; public class SimpleUserCredentials : ISimpleUserCredentials { public Guid? UserId { get; set; } public virtual void LoadFromJson(string json) { // TODO: Implement loading from JSON throw new NotImplementedException(); } public virtual string SaveToJson() { // TODO: Implement saving to JSON throw new NotImplementedException(); } } }
using System; namespace HelloExtensions.ProjectB.Auth.Entities { using Interfaces; public class UserCredentials : SimpleUserCredentials, IUserCredentials { public byte[] Token { get; set; } public override void LoadFromJson(string json) { // TODO: Implement loading from JSON throw new NotImplementedException(); } public override string SaveToJson() { // TODO: Implement saving to JSON throw new NotImplementedException(); } } }
using System; namespace HelloExtensions.ProjectB.Auth { using Interfaces; public class NonRegistrationSessionCredentials : INonRegistrationSessionCredentials { public byte[] Token { get; set; } public virtual void LoadFromJson(string json) { // TODO: Implement loading from JSON throw new NotImplementedException(); } public virtual string SaveToJson() { // TODO: Implement saving to JSON throw new NotImplementedException(); } } }
namespace HelloExtensions.ProjectB.Auth { using Interfaces; public interface IAuthProvider { INonRegistrationSessionCredentials AuthorizeSession(); ISimpleUserCredentials AuthorizeSimpleUser(string login, string password); IUserCredentials AuthorizeUser(string login, string password); } }
using System.Security.Cryptography; namespace HelloExtensions.ProjectB.Auth { using Entities; using Interfaces; internal sealed class AuthProvider : IAuthProvider { private static class TokenParams { public const int TokenHeaderSize = 8; public const int TokenBodySize = 64; public const int TokenSize = TokenHeaderSize + TokenBodySize; } private static void FillTokenHeader(byte[] token) { for (int i = 0; i < 2; i++) { token[i] = unchecked( (byte)((uint)TokenParams.TokenBodySize >> i * 8) ); } // TODO: Put Additional Info into the Token Header } private static void FillTokenBody(byte[] token) { using (var rng = RandomNumberGenerator.Create()) { rng.GetBytes(token, TokenParams.TokenHeaderSize, TokenParams.TokenBodySize); } } private static void StoreToken(byte[] token) { // TODO: Implement Token Storing in a Session Cache Manager } private static byte[] CreateToken() { byte[] token = new byte[TokenParams.TokenSize]; FillTokenHeader(token); FillTokenBody(token); return token; } public INonRegistrationSessionCredentials AuthorizeSession() { var credentials = new NonRegistrationSessionCredentials() { Token = CreateToken() }; StoreToken(credentials.Token); return credentials; } // TODO: Implement User Authorization public ISimpleUserCredentials AuthorizeSimpleUser(string login, string password) => new SimpleUserCredentials(); // TODO: Implement User Authorization public IUserCredentials AuthorizeUser(string login, string password) => new UserCredentials(); } }
using System; namespace HelloExtensions.ProjectB.Auth { public static class AuthProviderFactory { private static readonly Lazy<IAuthProvider> defaultInstance; static AuthProviderFactory() { defaultInstance = new Lazy<IAuthProvider>(Create); } public static IAuthProvider Create() => new AuthProvider(); public static IAuthProvider Default => defaultInstance.Value; } }
using HelloExtensions.Auth; namespace HelloExtensions { static class Program { static void Main(string[] args) { var authCredentialsA = ProjectA.Auth.AuthProviderFactory.Default .AuthorizeUser("user", "password"); bool authCredentialsAIsValid = authCredentialsA.IsValid(); var authCredentialsAEx = ProjectA.Auth.AuthProviderFactory.Default .AuthorizeUserEx("user", "password"); bool authCredentialsAExIsValid = authCredentialsAEx.IsValid(); var authCredentialsBSimple = ProjectB.Auth.AuthProviderFactory.Default .AuthorizeSimpleUser("user", "password"); bool authCredentialsBSimpleIsValid = authCredentialsBSimple.IsValid(); var authCredentialsB = ProjectB.Auth.AuthProviderFactory.Default .AuthorizeUser("user", "password"); bool authCredentialsBIsValid = authCredentialsB.IsValid(); var sessionCredentials = ProjectB.Auth.AuthProviderFactory.Default .AuthorizeSession(); bool sessionCredentialsIsValid = sessionCredentials.IsValid(); } } }
Source: https://habr.com/ru/post/314258/
All Articles