认证。课堂设计 [英] Authenticator. Class design

查看:62
本文介绍了认证。课堂设计的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

大家好!

我有一个基类 AuthenticatorBase ,能够使用不同的身份验证主题登录用户 - 登录&密码和令牌。

类看起来像这样:

Hi everyone!
I have a base class AuthenticatorBase that has ability to log in users with different authentication subjects - login & password and token.
Class looks like this:

 public abstract class AuthenticatorBase {

        public abstract LogInResult LogIn(object authSubject);

        public abstract void LogOut(string sessionKey);
}





使用login& ;;进行身份验证的子类密码





The sub-class that authenticates with login & password

public class BasicAuthenticator : AuthenticatorBase {

       public override LogInResult Authenticate(object authSubject) {
            LogInData credentials = authSubject as LogInData;
              
            if (DbContext.Security.Authorize(credentials))
              ...............
       }
    }





使用令牌进行身份验证的子类



The sub-class that authenticates with token

public class TokenBasedAuthenticator: AuthenticatorBase {

    public override LogInResult Authenticate(object authSubject)
    {
        string token = authSubject as string;

        User user;
        if (DbContext.Security.LogInWithToken(token, out user))
            ...........
    }
}



我在此代码中不喜欢的是类型 System.Object 的参数 authSubject ,我需要将其强制转换为子类。如果我使用,比如 BasicAuthenticator ,我可能会将无效类型作为参数传递。

我知道我可以制作泛型类型 AuthenticatorBase< TAuthSubject> 并且有两个子类 BasicAuthenticator:AuthenticatorBase< LogInData> TokenBasedAuthenticator :AuthenticatorBase< string> 。但是,如果我需要将它们放在列表中,那么通用类都没有通用接口。

我可以创建一个这样的附加界面:




What I don't like in this code is the parameter authSubject of type System.Object, I need to cast it in sub-classes. If I use, say BasicAuthenticator, I might pass invalid type as parameter.
I know I can make generic type AuthenticatorBase<TAuthSubject> and have two sub-classes BasicAuthenticator: AuthenticatorBase<LogInData> and TokenBasedAuthenticator : AuthenticatorBase<string>. But what if I need to have them in list, both generic classes don't have a common interface.
I could create an additional interface like this:

public interface IAuthenticator {

      LogInResult LogIn(object authSubject);
}

public abstract class AuthenticatorBase<tauthsubject>: IAuthenticator {

   public abstract LogInResult LogIn(TAuthSubject authSubject);

   // implementing interface
   LogInResult IAuthenticator.LogIn(object authSubject)
   {
       return LogIn((TAuthSubject)authSubject);
   }
}



现在我可以在列表中存储 IAuthenticator 的实例,但这似乎非常不知所措。什么是摆脱参数 authSubject 作为类型 System.Object 的最佳方法?我想调用它并将正确的类型实例传递给身份验证器,而不必考虑身份验证器接受的正确类型。谢谢



我尝试过:



试图使用我的代码,但我发现它重载


Now I can store instances of IAuthenticator in the list, but this seems to be very overwhelmed. What's the best way to get rid of the parameter authSubject as type System.Object??? I want to call it and pass correct instance of type to authenticators without having to think about correct types that authenticator accepts. Thanks

What I have tried:

Tried to use my code, but I find it overloaded

推荐答案

使用泛型是正确的方法,但是如果将它们添加到集合中就是问题,那么你可以让它们实现一个额外的像这样的界面



Using generics is the right way to go, however if adding them to a collection is the issue then you can make them implement an additional interface like this

public interface IAuthenticatorBase
{
    // you don't need to define this here, you could leave this interface
    // as an empty token interface
    void LogOut(string sessionKey);
}

public abstract class AuthenticatorBase<TAuthSubject> : IAuthenticatorBase
{
    public abstract LogInResult LogIn(TAuthSubject authSubject);

    public abstract void LogOut(string sessionKey);
}

public class BasicAuthenticator : AuthenticatorBase<LogInData>
{
    public override LogInResult LogIn(LogInData authSubject)
    {
        throw new NotImplementedException();
    }

    public override void LogOut(string sessionKey)
    {
        throw new NotImplementedException();
    }
}

public class TokenBasedAuthenticator : AuthenticatorBase<string>
{
    public override LogInResult LogIn(string authSubject)
    {
        throw new NotImplementedException();
    }

    public override void LogOut(string sessionKey)
    {
        throw new NotImplementedException();
    }
}





您将获得IAuthenticatorBase列表





You would then have a list of IAuthenticatorBase

List<IAuthenticatorBase> myAuths = new List<IAuthenticatorBase>();
myAuths.Add(new BasicAuthenticator());
myAuths.Add(new TokenBasedAuthenticator());

foreach (IAuthenticatorBase auth in myAuths)
{
    // this is where it gets a bit naff but if you want to
    // deal with disparate types in a collection then at some point you
    // have to convert them to their concrete versions
    if (auth is BasicAuthenticator)
    {
        BasicAuthenticator basicAuthenticator = auth as BasicAuthenticator;
    }
    else if (auth is TokenBasedAuthenticator)
    {
        TokenBasedAuthenticator tokenBasedAuthenticator = auth as TokenBasedAuthenticator;
    }
}


这篇关于认证。课堂设计的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆