我怎么能填充在Redis的值USERAUTH? [英] How can I populate a UserAuth from values in Redis?

查看:246
本文介绍了我怎么能填充在Redis的值USERAUTH?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是我在的Global.asax 文件我的自定义用户身份验证设置,但我目前手动提供用户在配置方法;是否有可能从Redis的服务器取值?

例如,如果用户存在,密码是好的,可以自动这些细节填?

Plugins.Add(新AuthFeature(()=>
    新AuthUserSession(),
    新IAuthProvider [] {新BasicAuthProvider()}
));container.Register&所述; ICacheClient>(新MemoryCacheClient());
VAR userRepo =新InMemoryAuthRepository();
container.Register< IUserAuthRepository>(userRepo);字符串的哈希,盐;
新SaltedHash()GetHashAndSaltString(密码,出来散,出盐);userRepo.CreateUserAuth(新USERAUTH
{
    ID = 1,
    显示名称=Haluk
    电子邮件=HAL
    用户名=haluk
    名字=haluk
    姓氏=耶尔马兹
    PasswordHash =散列,
    盐=盐
},密码);


解决方案

是的,你可以针对Redis的数据源进行身份验证。您可以使用内置的 RedisAuthRepository 代替了 InMemoryAuthRepository ,或者如果你有一个现有的Redis数据集要使用,而不是内置的 IAuthRepository 模式,我已经包括了一个解决方案,即你延长 BasicAuthProvider 。第一种方法是最简单的:

使用 RedisAuthRepository


  1. 所以,你需要建立的Redis连接。

  2. 然后注册您的身份验证提供。

  3. 注册 RedisAuthRepository ,其中认证供应商将核对证书,并与 RegistrationFeature

私人IRedisClientsManager redisClientsManager;公共覆盖无效配置(Funq.Container容器)
{
    //配置ServiceStack连接到的Redis
    //你的连接的详细信息替换
    redisClientsManager =新PooledRedisClientManager(127.0.0.1:6379);
    container.Register< IRedisClientsManager>(C => redisClientsManager);
    container.Register&所述; ICacheClient>(C => c.Resolve&下; IRedisClientsManager方式>()GetCacheClient())ReusedWithin(Funq.ReuseScope.None)。    //设置的授权功能
    Plugins.Add(新AuthFeature(()=>
        新AuthUserSession(),
        新IAuthProvider [] {新BasicAuthProvider()}
    ));    //使用RedisAuthRepository
    VAR userRepo =新RedisAuthRepository(redisClientsManager);
    container.Register< IUserAuthRepository>(userRepo);    //为使用RegistrationFeature您可以根据需要再注册用户
}


或者(如果你在Redis的现有用户身份验证数据集)

您可以通过创建扩展了现有的 BasicAuthProvider

有关此code你也应该确保你熟悉的的ServiceStack.Redis客户

延长 BasicAuthProvider

MyRedisBasicAuthProvider 扩展了现有的 BasicAuthProvider 和,而不是从 IUserAuthRepository 作为你的榜样code给出,它使一个Redis的连接,用户名在Redis的条目匹配。

在code是完全注释,但如果有任何你想进一步解释,让我知道。

公共类MyRedisBasicAuthProvider:BasicAuthProvider
{
    //在我们将存储用户配置文件的关键。即用户:或John.Smith或用户:homer.simpson
    //根据需要替换您的格式此键
    公共常量字符串UserKeyFormat =用户:{0};    MYUSER的currentUser;    //获取Redis的客户端的一个实例
    静态IRedisClient GetRedisClient()
    {
        //从容器中RedisClientsManager
        VAR redisClientManager = HostContext.TryResolve< IRedisClientsManager>();
        如果(redisClientManager == NULL)
            抛出新的异常(Redis是未配置);        //返回客户端
        返回redisClientManager.GetClient();
    }    //此方法用于验证提供的凭据
    公众覆盖布尔TryAuthenticate(IServiceBase authService,用户名字符串,字符串密码)
    {
        //获取一个Redis的客户端连接
        使用(VAR redisClient = GetRedisClient())
        {
            //获取一个类型的Redis客户端
            VAR userClient = redisClient.As<&MYUSER GT;();            //试图找到的Redis匹配的用户
            的currentUser = userClient.GetValue(的String.Format(UserKeyFormat,用户名));            //检查用户是否存在和放大器;他们的密码是正确的(你应该在这里使用一个哈希密码)
            返回的currentUser = NULL&放大器;!&安培;密码== CurrentUser.Password;
        }
    }    //该方法用于填充从用户配置文件和其他来源的数据的会话细节的要求
    公共覆盖IHtt presult OnAuthenticated(IServiceBase authService,IAuthSession会议,IAuthTokens令牌,字典<字符串,字符串> AUTHINFO)
    {
        //与当前用户的细节填充会话
        session.PopulateWith< IAuthSession,MYUSER>(的currentUser);        //保存会话
        authService.SaveSession(会话);        返回null;
    }    公共静态无效AddUserToRedis(MYUSER用户)
    {
        使用(VAR redisClient = GetRedisClient())
        {
            //获取一个类型的Redis客户端
            VAR userClient = redisClient.As<&MYUSER GT;();            //添加用户的Redis
            userClient.SetEntry(的String.Format(UserKeyFormat,user.Username),用户);
        }
    }
}

在code上面我已经使用了类 MYUSER 重新present,我已经存储在Redis的用户配置文件,你当然可以自定义这个类来匹配您的用户配置文件的要求。因此,这是基本的用户配置文件类:

公共类MYUSER
{
    公共字符串用户名{获得;组; }
    公共字符串密码{搞定;组; } //使用哈希密码替换
    公共字符串电子邮件{获得;组; }
    公共字符串名字{获得;组; }
    公共字符串名字{获得;组; }
}

与Redis的&安培设置ServiceStack;自定义身份验证提供者:

您将需要配置ServiceStack使用Redis的,并告诉它使用自定义身份验证提供者。您可以通过添加在以下到您的配置办法做到这一点你的 APPHOST

公共覆盖无效配置(Funq.Container容器)
{
    //配置ServiceStack连接到的Redis
    //你的连接的详细信息替换
    container.Register< IRedisClientsManager>(C =>新建PooledRedisClientManager(127.0.0.1:6379));
    container.Register&所述; ICacheClient>(C => c.Resolve&下; IRedisClientsManager方式>()GetCacheClient())ReusedWithin(Funq.ReuseScope.None)。    //添加自定义凭据提供
    Plugins.Add(新AuthFeature(()=>新建AuthUserSession()
        新IAuthProvider [] {
            新MyRedisBasicAuthProvider()
        }
    ));    //添加一些测试用户。 (如果你有一个现有的Redis的用户来源,你不会需要添加测试用户。)
    MyRedisBasicAuthProvider.AddUserToRedis(新MYUSER {
        用户名=和John.Smith
        密码=测试,
        电子邮件=john.smith@email.com
        名字=约翰,
        姓氏=史密斯
    });    MyRedisBasicAuthProvider.AddUserToRedis(新MYUSER {
        用户名=homer.simpson        密码=甜甜圈,
        电子邮件=homer.simpsons@springfield.com
        名字=荷马史诗,
        姓氏=辛普森
    });    //你的其他配置设置...
}

注:

在例子中,我没有使用哈希密码,以使例子简单,但是这是容易做到。添加其他字段公共字符串盐{搞定;组; } MYUSER 然后,而不是在 MYUSER 存储明文口令将其存储为密码和盐即 hashedPassword的HashAlgorithm =(密码+盐)的哈希值。你已经拥有code吧:

字符串哈希,盐;
新SaltedHash()GetHashAndSaltString(密码,出来散,出盐);

所以这个解决方案将现在使用Redis的一个数据源来验证用户时,服务使用 [授权] 属性担保。与标准基本提供商,凭据是在标准认证 / auth /中基本路线。

使用证书提供商,而不是基本的:

如果您要使用表单提交一个证书提供商,而不是基本身份验证,就可以简单的替换词基本证书在上面的code。

我希望这有助于。

This is my custom user authentication setup in my global.asax file, but I am currently providing the users manually in the Configure method; Is it possible to take values from a Redis server?

For example if user exists and the password is okay, can fill with these details automatically?

Plugins.Add(new AuthFeature(()=> 
    new AuthUserSession(), 
    new IAuthProvider[]{ new BasicAuthProvider() }
));

container.Register<ICacheClient>(new MemoryCacheClient());
var userRepo = new InMemoryAuthRepository();
container.Register<IUserAuthRepository>(userRepo);

string hash, salt;
new SaltedHash().GetHashAndSaltString("password", out hash, out salt);

userRepo.CreateUserAuth(new UserAuth
{
    Id = 1,
    DisplayName = "Haluk",
    Email = "hal",
    UserName = "haluk",
    FirstName = "haluk",
    LastName = "yılmaz",
    PasswordHash = hash,
    Salt = salt
}, "password");

解决方案

Yes you can authenticate against a Redis data source. You can either use the built in RedisAuthRepository in place of the InMemoryAuthRepository, or if you have an existing Redis data set that you want to use instead of the built-in IAuthRepository pattern, I have included a solution for that, whereby you extend the BasicAuthProvider. The first method is the most straightforward:

Use the RedisAuthRepository:

  1. So you need to establish a connection to Redis.
  2. Then register your authentication providers.
  3. Register the RedisAuthRepository, which the authentication providers will check credentials against, and is compatible with the RegistrationFeature

private IRedisClientsManager redisClientsManager;

public override void Configure(Funq.Container container)
{
    // Configure ServiceStack to connect to Redis
    // Replace with your connection details
    redisClientsManager = new PooledRedisClientManager("127.0.0.1:6379");
    container.Register<IRedisClientsManager>(c => redisClientsManager);
    container.Register<ICacheClient>(c => c.Resolve<IRedisClientsManager>().GetCacheClient()).ReusedWithin(Funq.ReuseScope.None);

    // Setup the authorisation feature
    Plugins.Add(new AuthFeature(()=> 
        new AuthUserSession(),
        new IAuthProvider[]{ new BasicAuthProvider() }
    ));

    // Use a RedisAuthRepository
    var userRepo = new RedisAuthRepository(redisClientsManager);
    container.Register<IUserAuthRepository>(userRepo);

    // You can then register users as required using the RegistrationFeature
}


Alternatively (if you have an existing user authentication dataset in Redis)

You can do this by creating a custom authentication provider that extends the existing BasicAuthProvider.

For this code you should also make sure that your familiar with the ServiceStack.Redis client.

Extend the BasicAuthProvider:

This MyRedisBasicAuthProvider extends the existing BasicAuthProvider, and instead of performing the credentials lookup from an IUserAuthRepository as given in your example code, it makes a Redis connection and matches the username to entry in Redis.

The code is fully commented but if there is anything you wish further explained, let me know.

public class MyRedisBasicAuthProvider : BasicAuthProvider
{
    // The key at which we will store the user profile. i.e user:john.smith or user:homer.simpson
    // Replace this key with your format as required
    public const string UserKeyFormat = "user:{0}";

    MyUser CurrentUser;

    // Gets an instance of a redis client
    static IRedisClient GetRedisClient()
    {
        // Get the RedisClientsManager from the Container
        var redisClientManager = HostContext.TryResolve<IRedisClientsManager>();
        if(redisClientManager == null)
            throw new Exception("Redis is not configured");

        // Return a client
        return redisClientManager.GetClient();
    }

    // This method is used to verify the credentials provided
    public override bool TryAuthenticate(IServiceBase authService, string userName, string password)
    {
        // Get a Redis client connection
        using(var redisClient = GetRedisClient())
        {
            // Get a typed Redis Client
            var userClient = redisClient.As<MyUser>();

            // Try to find a matching user in Redis
            CurrentUser = userClient.GetValue(string.Format(UserKeyFormat, userName));

            // Check the user exists & their password is correct (You should use a hashed password here)
            return CurrentUser != null && password == CurrentUser.Password;
        }
    }

    // This method is used to populate the session details from the user profile and other source data as required
    public override IHttpResult OnAuthenticated(IServiceBase authService, IAuthSession session, IAuthTokens tokens, Dictionary<string, string> authInfo)
    {
        // Populate the session with the details of the current user
        session.PopulateWith<IAuthSession, MyUser>(CurrentUser);

        // Save the session
        authService.SaveSession(session);

        return null;
    }

    public static void AddUserToRedis(MyUser user)
    {
        using(var redisClient = GetRedisClient())
        {
            // Get a typed Redis Client
            var userClient = redisClient.As<MyUser>();

            // Add the user to Redis
            userClient.SetEntry(string.Format(UserKeyFormat, user.Username), user);
        }
    }
}

In the code above I have used a class MyUser to represent the user profile that I have stored in Redis, you can of course customise this class to match your user profile requirements. So this is the basic user profile class:

public class MyUser
{
    public string Username { get; set; }
    public string Password { get; set; } // Replace with a hashed password
    public string Email { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
}

Setting up ServiceStack with Redis & your custom Authentication Provider:

You will need to configure ServiceStack to use Redis and tell it to use your custom authentication provider. You do this by adding the following to your Configure method in your AppHost:

public override void Configure(Funq.Container container)
{
    // Configure ServiceStack to connect to Redis
    // Replace with your connection details
    container.Register<IRedisClientsManager>(c => new PooledRedisClientManager("127.0.0.1:6379"));
    container.Register<ICacheClient>(c => c.Resolve<IRedisClientsManager>().GetCacheClient()).ReusedWithin(Funq.ReuseScope.None);

    // Add your custom credentials provider
    Plugins.Add(new AuthFeature(() => new AuthUserSession(),
        new IAuthProvider[] {
            new MyRedisBasicAuthProvider()
        }
    ));

    // Add some test users. (If you have an existing Redis user source, you won't need to add test users.)
    MyRedisBasicAuthProvider.AddUserToRedis(new MyUser {
        Username = "john.smith",
        Password = "test",
        Email = "john.smith@email.com",
        FirstName = "John",
        LastName = "Smith",
    });

    MyRedisBasicAuthProvider.AddUserToRedis(new MyUser {
        Username = "homer.simpson",

        Password = "donuts",
        Email = "homer.simpsons@springfield.com",
        FirstName = "Homer",
        LastName = "Simpson",
    });

    // Your other configuration settings ...
}

Notes:

In the example I haven't used a hash password, to keep the example straightforward, but this is trivial to do. Add another field public string Salt { get; set; } to the MyUser then instead of storing the plain password on MyUser store it as a hash of the password and salt i.e. hashedPassword = HashAlgorithm(password + salt). You already have code for it:

string hash, salt;
new SaltedHash().GetHashAndSaltString("password", out hash, out salt);

So this solution will now use a Redis data source to authenticate users when a service is secured using the [Authenticate] attribute. As with the standard basic provider, the credentials are authenticated at the standard /auth/basic route.

Using the Credentials provider instead of Basic:
If you want to use a credentials provider for form posts, instead of Basic authentication you can simple replace the word Basic with Credentials in the code above.

I hope this helps.

这篇关于我怎么能填充在Redis的值USERAUTH?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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