Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/257.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# ASP.NET MVC 5上的ASP.NET标识设置的Controller.User不一致_C#_Asp.net Mvc_Asp.net Mvc 5_Asp.net Identity_Owin - Fatal编程技术网

C# ASP.NET MVC 5上的ASP.NET标识设置的Controller.User不一致

C# ASP.NET MVC 5上的ASP.NET标识设置的Controller.User不一致,c#,asp.net-mvc,asp.net-mvc-5,asp.net-identity,owin,C#,Asp.net Mvc,Asp.net Mvc 5,Asp.net Identity,Owin,我试图将身份验证与控制器分离,因此我制作了一个AuthenticationService,并使用Ninject将其注入身份验证控制器(DefaultController)。下面是AuthenticationService的实现: public sealed class AuthenticationService { private IAuthenticationManager AuthenticationManager { get; set; } private UserMana

我试图将身份验证与控制器分离,因此我制作了一个
AuthenticationService
,并使用Ninject将其注入身份验证控制器(
DefaultController
)。下面是
AuthenticationService
的实现:

public sealed class AuthenticationService {
    private IAuthenticationManager AuthenticationManager { get; set; }
    private UserManager<Employee, int> EmployeeManager { get; set; }

    public AuthenticationService(
        IAuthenticationManager authenticationManager,
        UserManager<Employee, int> employeeManager) {
        this.AuthenticationManager = authenticationManager;
        this.EmployeeManager = employeeManager;
    }

    public bool SignIn(
        CredentialsInput credentials) {
        Employee employee = this.EmployeeManager.Find(credentials.Email, credentials.Password);

        if (employee != null) {
            ClaimsIdentity identityClaim = this.EmployeeManager.CreateIdentity(employee, DefaultAuthenticationTypes.ApplicationCookie);

            if (identityClaim != null) {
                this.AuthenticationManager.SignIn(new AuthenticationProperties(), identityClaim);

                return true;
            }
        }

        return false;
    }

    public void SignOut() {
        this.AuthenticationManager.SignOut(DefaultAuthenticationTypes.ApplicationCookie);
    }
}
哦,为了更好地衡量,这里是
DefaultController

public sealed class DefaultController : Controller {
    private AuthenticationService AuthenticationService { get; set; }

    public DefaultController(
        AuthenticationService authenticationService) {
        this.AuthenticationService = authenticationService;
    }

    [HttpPost, AllowAnonymous, ValidateAntiForgeryToken]
    public RedirectToRouteResult Default(
        [Bind(Prefix = "Credentials", Include = "Email,Password")] CredentialsInput credentials) {
        if (base.ModelState.IsValid
            && this.AuthenticationService.SignIn(credentials)) {
            //  Place of error. The IsInRole() method doesn't return
            //  the correct answer because the
            //  IUserStore<>.FindByIdAsync() method is not setting
            //  the correct data.
            if (this.User.IsInRole("Technician")) {
                return this.RedirectToAction<TechniciansController>(
                    c =>
                        c.Default());
            }

            return this.RedirectToAction(
                c =>
                    c.Dashboard());
        }

        return this.RedirectToAction(
            c =>
                c.Default());
    }

    [HttpGet]
    public RedirectToRouteResult SignOut() {
        this.AuthenticationService.SignOut();

        return this.RedirectToAction(
            c =>
                c.Default());
    }
}
嗯,我没有一个真正的解决办法,但我有一个有效的办法。由于在登录过程中未设置
用户
,因此我重定向到另一个名为
DefaultRedirect
的操作,在该操作中,我现在可以完全访问
用户
属性,并可以从那里重定向我真正想要的方式。这是一个肮脏的骗局,使事情顺利进行,但这不是一个真正的解决办法。我仍然认为ASP.NET标识在某种程度上无法正常工作。不管怎么说,这是我的骗局:

    [HttpPost, AllowAnonymous, ValidateAntiForgeryToken]
    public RedirectToRouteResult Default(
        [Bind(Prefix = "Credentials", Include = "Email,Password")] CredentialsInput credentials) {
        if (base.ModelState.IsValid
            && this.AuthenticationService.SignIn(credentials)) {
            return this.RedirectToAction(
                c =>
                    c.DefaultRedirect());
        }

        return this.RedirectToAction(
            c =>
                c.Default());
    }

    [HttpGet]
    public RedirectToRouteResult DefaultRedirect() {
        if (this.User.IsInRole("Technician")) {
            return this.RedirectToAction<TechniciansController>(
                c =>
                    c.Default());
        }

        return this.RedirectToAction(
            c =>
                c.Dashboard());
    }
[HttpPost,AllowAnonymous,ValidateAntiForgeryToken]
公共重定向路由结果默认值(
[Bind(Prefix=“Credentials”,Include=“Email,Password”)]Credentials输入凭据){
如果(base.ModelState.IsValid
&&此.AuthenticationService.SignIn(凭据)){
返回此.RedirectToAction(
c=>
c、 DefaultRedirect());
}
返回此.RedirectToAction(
c=>
c、 默认值());
}
[HttpGet]
公共重定向器路由结果DefaultRedirect(){
if(this.User.IsInRole(“技术人员”)){
返回此.RedirectToAction(
c=>
c、 默认值());
}
返回此.RedirectToAction(
c=>
c、 仪表板());
}

如果有人知道,我仍在寻找真正的解决方案

为了清楚起见--ASP.NET标识与在MVC中设置用户属性无关。这就是Katana身份验证中间件的工作。ASP.NET标识在数据库中管理用户的凭据和标识数据。我建议不要使用任务中的异步方法。任务中的异步方法使用IIS线程池中的线程,这意味着服务HTTP请求的线程更少。此外,由于方法
IsInRoleAsync()
的细节用于授权,因此调用线程无论如何都应该在继续(授权/拒绝)之前等待结果,这意味着使方法异步实际上会使进程变慢。完全同意@ErikPhilips。您不应该使用其他线程进行身份验证。他打电话给我的时候正在打it@ErikPhilips,我同意你的看法,但是所有的接口方法都是异步的,所以我没有选择的余地。我创建了我的实现,方法是用ILSpy在EF标识实现中进行搜索,并与它们所做的大部分匹配。我唯一不同的做法是使用我已经存在的存储库。也就是说,我在我的登录和注销方法中使用了同步扩展方法,它们只是异步方法的包装,我认为异步方法应该强制它们是同步的?对于那些感兴趣的人,我在回答这个问题时描述了我对ASP.NET Identity的实现:。
public sealed class DefaultController : Controller {
    private AuthenticationService AuthenticationService { get; set; }

    public DefaultController(
        AuthenticationService authenticationService) {
        this.AuthenticationService = authenticationService;
    }

    [HttpPost, AllowAnonymous, ValidateAntiForgeryToken]
    public RedirectToRouteResult Default(
        [Bind(Prefix = "Credentials", Include = "Email,Password")] CredentialsInput credentials) {
        if (base.ModelState.IsValid
            && this.AuthenticationService.SignIn(credentials)) {
            //  Place of error. The IsInRole() method doesn't return
            //  the correct answer because the
            //  IUserStore<>.FindByIdAsync() method is not setting
            //  the correct data.
            if (this.User.IsInRole("Technician")) {
                return this.RedirectToAction<TechniciansController>(
                    c =>
                        c.Default());
            }

            return this.RedirectToAction(
                c =>
                    c.Dashboard());
        }

        return this.RedirectToAction(
            c =>
                c.Default());
    }

    [HttpGet]
    public RedirectToRouteResult SignOut() {
        this.AuthenticationService.SignOut();

        return this.RedirectToAction(
            c =>
                c.Default());
    }
}
public Task<Employee> FindByIdAsync(
    int employeeId) {
    this.ThrowIfDisposed();

    return this.Repository.FindSingleOrDefaultAsync<Employee, int>(employeeId);
}

public Task<bool> IsInRoleAsync(
    Employee employee,
    string roleName) {
    this.ThrowIfDisposed();

    if (employee == null) {
        throw new ArgumentNullException("employee");
    }

    if (String.IsNullOrEmpty(roleName)) {
        throw new ArgumentNullException("roleName");
    }

    return Task.FromResult<bool>(employee.Roles.Any(
        r =>
            (r.Name == roleName)));
}
    [HttpPost, AllowAnonymous, ValidateAntiForgeryToken]
    public RedirectToRouteResult Default(
        [Bind(Prefix = "Credentials", Include = "Email,Password")] CredentialsInput credentials) {
        if (base.ModelState.IsValid
            && this.AuthenticationService.SignIn(credentials)) {
            return this.RedirectToAction(
                c =>
                    c.DefaultRedirect());
        }

        return this.RedirectToAction(
            c =>
                c.Default());
    }

    [HttpGet]
    public RedirectToRouteResult DefaultRedirect() {
        if (this.User.IsInRole("Technician")) {
            return this.RedirectToAction<TechniciansController>(
                c =>
                    c.Default());
        }

        return this.RedirectToAction(
            c =>
                c.Dashboard());
    }