Authentication ServiceStack-电子邮件确认
我正在尝试在ServiceStack中实现电子邮件确认。我花了5天时间试图弄清楚所有的身份验证机制,我必须说它非常复杂。代码不容易阅读 我很难知道,例如:Authentication ServiceStack-电子邮件确认,authentication,asp.net-core,.net-core,authorization,servicestack,Authentication,Asp.net Core,.net Core,Authorization,servicestack,我正在尝试在ServiceStack中实现电子邮件确认。我花了5天时间试图弄清楚所有的身份验证机制,我必须说它非常复杂。代码不容易阅读 我很难知道,例如: 为什么调用IAuthProvider.OnAuthenticated?有时它似乎是可选的 为什么调用IAuthSession.PopulateSession?它与IAuthProvider.PopulateSession有何不同 为什么调用IRequest.SaveSession 什么是IAuthTokens?为什么他们会在某个时候合并?这
- 为什么调用
?有时它似乎是可选的IAuthProvider.OnAuthenticated
- 为什么调用
?它与IAuthProvider.PopulateSession有何不同IAuthSession.PopulateSession
- 为什么调用
IRequest.SaveSession
- 什么是
?为什么他们会在某个时候合并?这是因为用户可以通过许多不同的提供者进行身份验证,并且我们需要合并IAuthTokens
?它们像索赔吗IAuthTokens
是否仅适用于JWTSession.FromToken
和IAuthWithRequest.PreAuthenticate
有何不同?在这两种方法中有什么不同的做法?我推测每个请求都会调用预身份验证,使用/auth/{provider}(在本例中为/auth/email)时会调用Authenticate。我错过什么了吗IAuthProvider.Authenticate
bool-emailconfirm{get;set;}
字段,用CustomUserAuth
覆盖默认的UserAuth
EmailConfirmationAuthenticationProvider.PreAuthentication
会将CustomUserAuth.EmailConfirmation
标记为true(如果令牌有效且未过期)。令牌被删除,因此无法再次使用该令牌进行身份验证emailconfirm=true
添加到会话中,也不知道如何在后续登录时添加它。我不知道怎样才能不妨碍其他身份验证机制电子邮件确认服务
EmailConfirmationService
将CustomUserAuth.EmailConfirmation
标记为true。令牌已删除,无法重复使用同一令牌CustomUserAuth
重新填充会话,特别是如果用户已经使用JWT令牌进行了身份验证(如果JwtAuthProvider
是AuthFeature.AuthProviders
的一部分)。我想找到一种方法,为该用户的所有后续登录向会话添加EmailConfirm标志。我没有找到如何“修改”JWT令牌(通过添加emailconfirm=true),并将其作为cookie发送回去,这样就不必检查电子邮件是否在每个请求中都得到了确认[Authenticate]
的所有服务。如果我错了,请纠正我,但这应该只适用于使用凭据注册的用户(如果用户使用GoogleAuthProvider
登录,则不应使用电子邮件确认。或者应该这样做?)
此规则的例外情况是某些服务(用属性标记,例如
[AllowUnconfirmedMail]
)允许用户向其地址重新发送确认电子邮件(例如输入了错误的电子邮件地址)。EmailConfirmationService
允许经过身份验证的用户向新地址发送新确认。单击该确认电子邮件后,CustomUserAuth.email和CustomUserAuth.PrimaryEmail将使用新地址更新。请参考中的高级图表,以解释其工作原理
这些问题中有很多是内部实现细节,当不同的身份验证提供者需要它们时,就会调用它们。可以向其中添加自定义逻辑的用户可重写事件将在中发布
PreAuthenticate()<通过/auth
提供程序进行身份验证时,会调用code>Authenticate()
实现am电子邮件确认
实现需要确认电子邮件的用户的最简单方法可能是实现类似以下内容的电子邮件:
public class CustomUserSession : AuthUserSession
{
public override IHttpResult Validate(IServiceBase authService, IAuthSession session,
IAuthTokens tokens, Dictionary<string, string> authInfo)
{
using (var db = HostContext.AppHost.GetDbConnection(authService.Request))
{
var userAuthId = int.Parse(session.UserAuthId);
if (!db.Exists<CustomUserAuth>(x => x.Id == userAuthId && x.EmailConfirmed))
return HttpError.Conflict($"Email not confirmed") as IHttpResult;
}
return null;
}
}
这样,您就可以在同一个“进程中”请求中仅使用用户名进行身份验证:
using (var service = base.ResolveService<AuthenticateService>()) //In Process
{
return service.Post(new Authenticate {
provider = AuthenticateService.CredentialsProvider,
UserName = request.UserName,
UseTokenCookie = true, // if using JWT
});
}
使用(var service=base.ResolveService),尽管不需要使用JWT
此解决方案不需要它,但您可以通过实现PopulateSessionFilter
将附加信息添加到JWT令牌,并在用户会话上填充该附加元数据
我不知道如何将emailconfirm=true添加到会话中
您可以通过在自定义的AuthUserSession
上实现OnAuthenticated()
来填充UserSession
基本上,我想将所有标有[Authenticate]的服务的访问权限限制为已确认其电子邮件地址的用户
如上所述,在自定义AuthUserSession中重写Validate()
,将确保只有具有已确认电子邮件的用户才能进行身份验证
此规则的例外情况是某些服务
没有“部分身份验证用户”的概念—您要么通过身份验证(并且将身份验证用户会话附加到请求或缓存)或者你不是。我只允许他们确认他们的电子邮件时进行身份验证,只有他们确认了他们要更改的建议电子邮件时才更新他们的确认电子邮件。谢谢你的回答。我开始遵循这些准则。CreadentialAuthProvider似乎没有打电话给我
using (var service = base.ResolveService<AuthenticateService>()) //In Process
{
return service.Post(new Authenticate {
provider = AuthenticateService.CredentialsProvider,
UserName = request.UserName,
UseTokenCookie = true, // if using JWT
});
}