- r - 以节省内存的方式增长 data.frame
- ruby-on-rails - ruby/ruby on rails 内存泄漏检测
- android - 无法解析导入android.support.v7.app
- UNIX 域套接字与共享内存(映射文件)
这是我在 global.asax
文件中的自定义用户身份验证设置,但我目前在 Configure
方法中手动提供用户;是否可以从 Redis 服务器获取值?
例如如果用户存在且密码没问题,是否可以自动填写这些详细信息?
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");
最佳答案
是的,您可以针对 Redis 数据源进行身份验证。您可以使用内置的 RedisAuthRepository
代替 InMemoryAuthRepository
,或者如果您有想要使用的现有 Redis 数据集而不是内置的 IAuthRepository
模式,我为此提供了一个解决方案,您可以借此扩展 BasicAuthProvider
。第一种方法最直接:
RedisAuthRepository
:RedisAuthRepository
,身份验证提供程序将根据它检查凭据,并且与 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
}
您可以通过创建自定义身份验证提供程序来做到这一点 extends the existing BasicAuthProvider
.
对于此代码,您还应确保熟悉 the ServiceStack.Redis client .
BasicAuthProvider
:此 MyRedisBasicAuthProvider
扩展了现有的 BasicAuthProvider
,而不是从示例代码中给出的 IUserAuthRepository
执行凭据查找,它使Redis 连接并将用户名与 Redis 中的条目匹配。
代码已完全注释,但如果您希望进一步解释任何内容,请告诉我。
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);
}
}
}
在上面的代码中,我使用了一个类 MyUser
来表示我存储在 Redis 中的用户配置文件,您当然可以自定义此类以满足您的用户配置文件要求。所以这是基本的用户配置文件类:
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; }
}
您需要配置 ServiceStack 以使用 Redis 并告诉它使用您的自定义身份验证提供程序。为此,您可以将以下内容添加到 AppHost
中的 Configure
方法:
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 ...
}
在示例中,我没有使用散列密码,以保持示例简单明了,但这很容易做到。添加另一个字段 public string Salt { get;放; }
到 MyUser
然后不是将纯密码存储在 MyUser
上,而是将其存储为密码和盐的散列,即 hashedPassword = HashAlgorithm(password + 盐)
。您已经有了它的代码:
string hash, salt;
new SaltedHash().GetHashAndSaltString("password", out hash, out salt);
因此,当使用 [Authenticate]
属性保护服务时,此解决方案现在将使用 Redis 数据源对用户进行身份验证。与标准基本提供程序一样,凭据在标准 /auth/basic
路由中进行身份验证。
使用 Credentials provider 而不是 Basic:
如果您想为表单发布使用凭据提供程序,而不是基本身份验证,您可以简单地将上面代码中的单词 Basic
替换为 Credentials
。
希望对您有所帮助。
关于redis - 如何从 Redis 中的值填充 UserAuth?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24798360/
padding:initial 比 padding:0 有什么优势吗?示例: textarea { padding: 0; } Hello, world! 最佳答案 它们的意思是一
我尝试通过按钮填充 JList,然后在先前填充的 Jlist 上使用 DoubleClick 填充 JTextField。 代码: private void extractUsedVariables
我正在尝试做 var width = ($(this).width() + $(this).css('padding-left') + $(this).css('padding-right' ));
我在导航中添加了悬停效果,遗憾的是悬停也影响了上面的文字。如何在不影响文本位置的情况下向导航添加悬停? 可悲的是,我找不到解决这个问题的方法。 HTML 模板:http://projects.help
我是 F# 初学者,下面代码中的 %-5s 和 %5s 有什么作用?我认为它提供了空间填充,但我不确定它是如何填充的? printfn "%-5s %5s" "a" "b" 当我尝试 prin
我需要选择带狗的用户(带 type 等于“狗”的宠物) var User = Waterline.Collection.extend({ identity: 'user', attribute
我一直在尝试让 Excel 在一组列上应用公式,然后将模式扩展到整个行集。 这导致了以下代码: For i = 0 To avgsheetNames.Count - 1 If Contains(CSt
随着 Flutter 2.0 的发布,FlatButton已被替换为 TextButton . 因此,填充属性不再直接可用,而是作为 ButtonStyle属性(property)。 我的问题是,我该
这似乎是一个简单的问题,但我已经尝试了一个小时,似乎无法弄清楚。 我要做的就是用 Canvas 填充 MainWindow。我找不到任何允许这样做的属性,我能想到的唯一方法是设置 Canvas.Wid
这是a website具有移动 View 。 网站宽度为 640 像素,但 iPhone 以 678 像素渲染文档。在 Android 中看起来很棒。 我添加了视口(viewport)元: 主体 C
我正在使用 GridBagLayout到(当前)显示两行。我知道这种布局对于这项任务来说太过分了,但我正在努力学习如何使用它。问题是我已将两个面板添加到两个单独的行中,并且内容周围存在巨大差距(请参见
我有以下代码已传递给我并创建多边形: var map; function initialize() { var myLatlng = new google.maps.LatLng(-36.4
我在 Jpanel 中有一些项目,然后将其推到顶部并用作基本搜索引擎的工具栏。我遇到一个问题,因为没有足够的空间,所以我的最后一个组合框没有显示。但是,左侧有很多空白空间,我需要移动所有内容来填充 J
我创建了带有阈值的二进制图像。如下图所示如何改变白色形状的颜色以使其可索引? 到目前为止,这是我的代码: void threshold() { cv::Mat src_8uc3_img = c
我有一个 JTable,我想知道是否有更好的方法来填充它,这是我的代码: //Metodo para llenar un jtable con datos de la base public stat
我想要做的是裁剪一个卷以删除所有不相关的数据。例如,假设我有一个 100x100x100 的体积,其中填充了 0,但其中的 50x50x50 体积则填充了 1。如何从原始体积中获得裁剪后的 50x50
因此,我正在创建一种对一组数字进行洗牌的方法,其想法是创建这些数字的总体。因此,我创建了一个循环,对数字进行洗牌,然后将其添加到数组列表中,但是经过一些调试语句后,我发现它确实对数字进行洗牌,但只将最
假设我有这两个类: public class A where T : IEntityWithID, new() { private static EntityInfo entityInfo =
我正在尝试添加用户输入的两个大整数作为字符串。当两个输入字符串的长度不同时,我尝试用零填充较短的数字,但它不起作用。因此,如果我输入 456 和 7,它会给出 3,前面有一些随机字符。感谢您的任何建议
这是我将内容打印到表格 View 的代码 override func tableView(_ tableView: UITableView, cellForRowAt indexPath: Index
我是一名优秀的程序员,十分优秀!