Feedback

C# - Token basierte Authentifikation

Veröffentlicht von am 23.04.2016
(0 Bewertungen)
Einfache Authentifikation mithlfe von Pointer, durch die Configure-Methoe kann ich die Authentifizierungslogik injezieren

Beispiel:
var p = new AuthPrincipal();

p.Configure((roles, user) =>
{
if(user.Username == "admin" && user.Password == "admin123")
{
roles.Add("Administrator");
roles.Add("Moderator");
return true;
}
return false;
});

var token = p.Logon("admin", "admin123");

Thread.CurrentPrincipal = p;
internal class AuthPrincipal : IPrincipal
    {
        private List<string> _roles = new List<string>();
        private Func<List<string>, User, bool> _authenticator;

        public bool IsAuthed { get; set; }
        public string Name { get; set; }

        public AuthPrincipal()
        {
        }

        public void Configure(Func<List<string>, User, bool> authenticator)
        {
            _authenticator = authenticator;
        }

        public AuthPrincipal(IntPtr ptr)
        {
            Auth(ptr);
        }

        public bool Auth(IntPtr ptr)
        {
            var user = Marshal.PtrToStructure<User>(ptr);

            IsAuthed = _authenticator(_roles, user);

            if(IsAuthed)
            {
                Name = user.Username;
            }

            return IsAuthed;
        }

        public IntPtr Logon(string username, string password)
        {
            var us = new User();
            us.Username = username;
            us.Password = password;

            IntPtr ptr = Marshal.AllocHGlobal(Marshal.SizeOf(us));

            Marshal.StructureToPtr(us, ptr, false);
            Auth(ptr);

            return ptr;
        }

        public IIdentity Identity
        {
            get
            {
                if (!IsAuthed) return null;

                return new AuthIdentity(this);
            }
        }

        public bool IsInRole(string role)
        {
            if (_roles.Count == 0) throw new UnauthorizedAccessException("User not logged in");

            return _roles.Contains(role);
        }
    }

    internal struct User
    {
        public string Username { get; set; }
        public string Password { get; set; }
    }

    internal class AuthIdentity : IIdentity
    {
        public string AuthenticationType => "System";

        private bool _authed;
        private string _name;
        private AuthPrincipal authPrincipal;

        public AuthIdentity(AuthPrincipal authPrincipal)
        {
            this.authPrincipal = authPrincipal;

            this._authed = authPrincipal.IsAuthed;
            this._name = authPrincipal.Name;
        }

        public bool IsAuthenticated => _authed;

        public string Name => _name;
    }
Abgelegt unter token, pointer, authentication.

3 Kommentare zum Snippet

Koopakiller schrieb am 25.04.2016:
Wozu der Umweg über das IntPtr? Ich sehe darin keine Vorteile, nur Nachteile.
cueware schrieb am 01.01.2018:
Was wären denn die Nachteile?
Koopakiller schrieb am 01.01.2018:
Am wichtigsten: Die Vorteile der Typisierung gehen verloren. Man kann einfach den IntPtr eines anderen Objekts übergeben, woraus dann allerdings kein sinnvolles User-Objekt mehr erstellt werden kann.
Es vergrößert außerdem die Gefahr, dass man aus Versehen die falsche Variable übergibt, weil man auch noch andere IntPtr-Variablen verwendet.
 

Logge dich ein, um hier zu kommentieren!