问题描述
这是我在的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
:
- 所以,你需要建立的Redis连接。
- 然后注册您的身份验证提供。
- 注册
RedisAuthRepository
,其中认证供应商将核对证书,并与RegistrationFeature
兼容LI>
私人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你也应该确保你熟悉的。
延长 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
密码=测试,
电子邮件[email protected]
名字=约翰,
姓氏=史密斯
}); MyRedisBasicAuthProvider.AddUserToRedis(新MYUSER {
用户名=homer.simpson 密码=甜甜圈,
电子邮件[email protected]
名字=荷马史诗,
姓氏=辛普森
}); //你的其他配置设置...
}
注:
在例子中,我没有使用哈希密码,以使例子简单,但是这是容易做到。添加其他字段公共字符串盐{搞定;组; }
到 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
:
- So you need to establish a connection to Redis.
- Then register your authentication providers.
- Register the
RedisAuthRepository
, which the authentication providers will check credentials against, and is compatible with theRegistrationFeature
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 = "[email protected]",
FirstName = "John",
LastName = "Smith",
});
MyRedisBasicAuthProvider.AddUserToRedis(new MyUser {
Username = "homer.simpson",
Password = "donuts",
Email = "[email protected]",
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?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!