ServiceStack 中带有自定义身份验证提供程序的 ArgumentNullException

ArgumentNullException with custom auth provider in ServiceStack

我已经基于 CredentialsAuthProvider 为 LDAP (Active Directory) 创建了一个自定义身份验证提供程序。按照文档,我已经覆盖了 TryAuthenticate 和 OnAuthenticated,最后返回 true。我也尝试过不使用 OnAuthenticated。

我正在为 OrmLiteAuthRepository 使用 UseDistinctRoleTables,并且我在表中观察到角色是在 UserRole 中创建的。

但是我遇到了异常:ArgumentNullException。字段名 "s".

"stackTrace": "[Authenticate: 20/03/2020 16:46:30]:
[REQUEST: {provider:Credentials,userName:xxxx,password:yyyy}]
System.ArgumentNullException: Value cannot be null.
Parameter name: s
   at lambda_method(Closure , Object , List`1 )
   at ServiceStack.OrmLite.SqlExpression`1.EvaluateExpression(Expression m) in C:\BuildAgent\work\27e4cc16641be8c0\src\ServiceStack.OrmLite\Expressions\SqlExpression.cs:line 2374
   at ServiceStack.OrmLite.SqlExpression`1.VisitBinary(BinaryExpression b) in C:\BuildAgent\work\27e4cc16641be8c0\src\ServiceStack.OrmLite\Expressions\SqlExpression.cs:line 1658
   at ServiceStack.OrmLite.SqlExpression`1.VisitBinary(BinaryExpression b) in C:\BuildAgent\work\27e4cc16641be8c0\src\ServiceStack.OrmLite\Expressions\SqlExpression.cs:line 1622
   at ServiceStack.OrmLite.SqlExpression`1.VisitLambda(LambdaExpression lambda) in C:\BuildAgent\work\27e4cc16641be8c0\src\ServiceStack.OrmLite\Expressions\SqlExpression.cs:line 1589
   at ServiceStack.OrmLite.SqlExpression`1.AppendToWhere(String condition, Expression predicate) in C:\BuildAgent\work\27e4cc16641be8c0\src\ServiceStack.OrmLite\Expressions\SqlExpression.cs:line 555
   at ServiceStack.OrmLite.ReadExpressionCommandExtensions.Select[T](IDbCommand dbCmd, Expression`1 predicate) in C:\BuildAgent\work\27e4cc16641be8c0\src\ServiceStack.OrmLite\Expressions\ReadExpressionCommandExtensions.cs:line 22
   at ServiceStack.OrmLite.OrmLiteExecFilter.Exec[T](IDbConnection dbConn, Func`2 filter) in C:\BuildAgent\work\27e4cc16641be8c0\src\ServiceStack.OrmLite\OrmLiteExecFilter.cs:line 64
   at ServiceStack.Auth.OrmLiteAuthRepositoryBase`2.<>c__DisplayClass33_0.<GetRoles>b__0(IDbConnection db) in C:\BuildAgent\work\3481147c480f4a2f\src\ServiceStack.Server\Auth\OrmLiteAuthRepository.cs:line 571
   at ServiceStack.Auth.OrmLiteAuthRepository`2.Exec[T](Func`2 fn) in C:\BuildAgent\work\3481147c480f4a2f\src\ServiceStack.Server\Auth\OrmLiteAuthRepository.cs:line 51
   at ServiceStack.Auth.AuthenticateService.Post(Authenticate request) in C:\BuildAgent\work\3481147c480f4a2f\src\ServiceStack\Auth\AuthenticateService.cs:line 231
   at ServiceStack.Host.ServiceRunner`1.ExecuteAsync(IRequest req, Object instance, TRequest requestDto) in C:\BuildAgent\work\3481147c480f4a2f\src\ServiceStack\Host\ServiceRunner.cs:line 133",

我精简了我的代码。在 Startup.cs:

Plugins.Add(new AuthFeature( () => new AuthUserSession(),
            new IAuthProvider[] {
                new LdapCredentialsAuthProvider(AppSettings),

问题是 ServiceStack 的 AuthenticateService 正在尝试填充 AuthenticateResponse 角色和权限,但您的自定义 AuthProvider 没有填充用于查询 Auth 存储库的 session.UserAuthId角色。

您的自定义 AuthProvider 的解决方案是使用经过身份验证的用户的 ID 填充会话 UserAuthId

您还可以通过设置 IncludeRolesInAuthenticateResponse=false 禁用 ServiceStack 尝试填充 Roles/Permissions 来防止此异常,例如:

Plugins.Add(new AuthFeature( () => new AuthUserSession(),
    new IAuthProvider[] {
        new LdapCredentialsAuthProvider(AppSettings),                     
    }, 
    "/login.html"
) {
    IncludeRolesInAuthenticateResponse = false,
});

在接下来的 ServiceStack v5.8.1 now on MyGet 中,如果 UserAuthId 未填充,它不会尝试检索角色,但您的自定义 AuthProvider 仍应使用经过身份验证的用户的唯一 ID 填充它.