我正在尝试使用自托管Nancy创建表单身份验证。为了简单起见,没有用户数据的数据库,它存储在List.We有两个用户:
U:admin P:passowrd
U:用户P:密码
我正在使用:
Get["/login"] = x =>
{
Model.login = new LoginModel() { Error = this.Request.Query.error.HasValue, ReturnUrl = this.Request.Url };
return View["login", Model];
};
Post["/login"] = x =>
{
var userGuid = MyUserMapper.ValidateUser((string) this.Request.Form.Username,
(string) this.Request.Form.Password);
if (userGuid == null)
{
return Context.GetRedirect("~/login?error=true&username=" +
(string) this.Request.Form.Username);
}
DateTime? expiry = null;
if (this.Request.Form.RememberMe.HasValue)
{
expiry = DateTime.Now.AddDays(7);
}
return this.LoginAndRedirect(userGuid.Value, expiry);
我的登录模块:
return this.LoginAndRedirect(userGuid.Value, expiry);
An exception of type 'System.NullReferenceException' occurred in Nancy.Authentication.Forms.dll but was not handled in user code
当输入错误的用户/密码时,一切正常。当输入正确的用户/密码时,在LoginAndRedirect上发生NullReferenceException:
> NancyLinuxTest.exe!NancyLinuxTest.Models.MainModule..ctor.AnonymousMethod__16(dynamic x) Line 49 C#
调用堆栈:
Nancy.Authentication.Forms.FormsAuthentication.EncryptAndSignCookie(String cookieValue, FormsAuthenticationConfiguration configuration)\r\n at Nancy.Authentication.Forms.FormsAuthentication.BuildCookie(Guid userIdentifier, Nullable`1 cookieExpiry, FormsAuthenticationConfiguration configuration)\r\n at Nancy.Authentication.Forms.FormsAuthentication.UserLoggedInRedirectResponse(NancyContext context, Guid userIdentifier, Nullable`1 cookieExpiry, String fallbackRedirectUrl)\r\n at Nancy.Authentication.Forms.ModuleExtensions.LoginAndRedirect(INancyModule module, Guid userIdentifier, Nullable`1 cookieExpiry, String fallbackRedirectUrl)\r\n at NancyLinuxTest.Models.MainModule.<.ctor>b__16(Object x) in d:\\prototype-prices\\for_delete\\#proto\\NancyFormAuthTest\\NancyFormAuthTest\\Modules\\MainModule.cs:line 55\r\n at CallSite.Target(Closure , CallSite , Func`2 , Object )\r\n at Nancy.Routing.Route.<>c__DisplayClass4.<Wrap>b__3(Object parameters, CancellationToken context)
堆栈追踪:
<?php
namespace Illuminate\Mail;
use Swift_Mailer;
use Illuminate\Support\Arr;
use Illuminate\Support\Str;
use Illuminate\Support\ServiceProvider;
class MailServiceProvider extends ServiceProvider
{
/**
* Indicates if loading of the provider is deferred.
*
* @var bool
*/
protected $defer = true;
/**
* Register the service provider.
*
* @return void
*/
public function register()
{
$this->registerSwiftMailer();
$this->registerIlluminateMailer();
$this->registerMarkdownRenderer();
}
/**
* Register the Illuminate mailer instance.
*
* @return void
*/
protected function registerIlluminateMailer()
{
$this->app->singleton('mailer', function ($app) {
$config = $app->make('config')->get('mail');
// Once we have create the mailer instance, we will set a container instance
// on the mailer. This allows us to resolve mailer classes via containers
// for maximum testability on said classes instead of passing Closures.
$mailer = new Mailer(
$app['view'], $app['swift.mailer'], $app['events']
);
if ($app->bound('queue')) {
$mailer->setQueue($app['queue']);
}
// Next we will set all of the global addresses on this mailer, which allows
// for easy unification of all "from" addresses as well as easy debugging
// of sent messages since they get be sent into a single email address.
foreach (['from', 'reply_to', 'to'] as $type) {
$this->setGlobalAddress($mailer, $config, $type);
}
return $mailer;
});
}
/**
* Set a global address on the mailer by type.
*
* @param \Illuminate\Mail\Mailer $mailer
* @param array $config
* @param string $type
* @return void
*/
protected function setGlobalAddress($mailer, array $config, $type)
{
$address = Arr::get($config, $type);
if (is_array($address) && isset($address['address'])) {
$mailer->{'always'.Str::studly($type)}($address['address'], $address['name']);
}
}
/**
* Register the Swift Mailer instance.
*
* @return void
*/
public function registerSwiftMailer()
{
$this->registerSwiftTransport();
// Once we have the transporter registered, we will register the actual Swift
// mailer instance, passing in the transport instances, which allows us to
// override this transporter instances during app start-up if necessary.
$this->app->singleton('swift.mailer', function ($app) {
return new Swift_Mailer($app['swift.transport']->driver());
});
}
/**
* Register the Swift Transport instance.
*
* @return void
*/
protected function registerSwiftTransport()
{
$this->app->singleton('swift.transport', function ($app) {
return new TransportManager($app);
});
}
/**
* Register the Markdown renderer instance.
*
* @return void
*/
protected function registerMarkdownRenderer()
{
if ($this->app->runningInConsole()) {
$this->publishes([
__DIR__.'/resources/views' => $this->app->resourcePath('views/vendor/mail'),
], 'laravel-mail');
}
$this->app->singleton(Markdown::class, function ($app) {
$config = $app->make('config');
return new Markdown($app->make('view'), [
'theme' => $config->get('mail.markdown.theme', 'default'),
'paths' => $config->get('mail.markdown.paths', []),
]);
});
}
/**
* Get the services provided by the provider.
*
* @return array
*/
public function provides()
{
return [
'mailer', 'swift.mailer', 'swift.transport', Markdown::class,
];
}
}
userGuid.Value不为空。
答案 0 :(得分:1)
发现我的问题,我正在调用错误的Bootstrapper :)。
答案 1 :(得分:0)
private static string EncryptAndSignCookie(string cookieValue, FormsAuthenticationConfiguration configuration)
{
var encryptedCookie = configuration.CryptographyConfiguration.EncryptionProvider.Encrypt(cookieValue);
var hmacBytes = GenerateHmac(encryptedCookie, configuration);
var hmacString = Convert.ToBase64String(hmacBytes);
return String.Format("{1}{0}", encryptedCookie, hmacString);
}
可以触发NRE的唯一行(v.1.4.1)是configuration
尊重。如果查看代码,可以通过调用Enable
来设置。在那里开始调查,看看调用Enable
的时间,检查传入的配置。
免责声明:我不知道南希是什么,也不关心。这是您应该做的基本代码调试。都是开源的。只需单步执行即可。