3

J'ai une application MVC avec authentification basée sur des formulaires avec Principal personnalisé. Avant d'utiliser l'application, l'utilisateur doit se connecter. Après cela, je veux utiliser SignalR, le problème est que Context.User.Identity.Name est toujours une chaîne vide.Passer IPrincipal de MVC à SignalR

CustomPrincipal.cs

public class CustomPrincipal : IPrincipal 
{ 
    public CustomPrincipal(IIdentity identity) 
    { 
     Identity = identity; 
    } 

    public IIdentity Identity { get; } 

    public bool IsInRole(string role) 
    { 
     return true; 
    } 
} 

CustomIdentity.cs

public class CustomIdentity : IIdentity 
{ 
    public CustomIdentity(EmployeeModel user) 
    { 
     Name = user.Username; 
     Id = user.Id; 
    } 

    public string AuthenticationType => "Custom"; 

    public bool IsAuthenticated => !string.IsNullOrEmpty(Name); 

    public int Id { get; set; } 

    public string Name { get; } 
} 

BaseController.cs (dont je tire tous mes contrôleurs MVC)

protected override void OnAuthorization(AuthorizationContext context) 
{ 
    if (SessionPersister.User != null && !string.IsNullOrEmpty(SessionPersister.User.Username)) 
    { 
     context.HttpContext.User = new CustomPrincipal(new CustomIdentity(SessionPersister.User)); 
    } 

    base.OnAuthorization(context); 
} 

SessionPersister est ici juste statique classe pour stocker les utilisateurs connectés

Ainsi, tout dans mon application MVC fonctionne très bien. La question que lorsque l'utilisateur est connecté et je veux envoyer un message à un autre utilisateur qui est connecté via SignalR, Identity.User.Name est une chaîne vide dans ma classe de Hub:

public override Task OnConnected() 
{ 
    string name = Context.User.Identity.Name; // it's empty 

    return base.OnConnected(); 
} 

est-il est un moyen de passer mon MVC IPrincipal à SignalR ou le configurer pour utiliser mon authentification personnalisée, que j'utilise dans MVC?

Merci à l'avance

+0

Quelle version de ASP.NET MVC? –

+1

Je suis confronté au même problème, une mise à jour? –

Répondre

1

Ainsi, une légère erreur logique:

BaseController.OnAuthorization déclenche uniquement lorsqu'un contrôleur est en cours d'exécution. Lorsqu'une requête SignalR arrive, cette méthode ne sera jamais appelée pour cette requête. Donc, un moyen de contourner cela serait de déplacer le code du contrôleur vers une portée plus globale. Par exemple, vous pouvez utiliser le Global.asax.cs et l'ajouter, likeso:

protected void Application_PostAuthenticateRequest(object sender, EventArgs e) 
    { 
     //do your custom principal setting here. 
     this.Context.User = new CustomPrincipal(new CustomIdentity(10, "test")); 
    } 

Ensuite, dans votre centre, vous seriez en mesure de voir l'identité comme ceci:

public String Hello(String hello) 
    { 
     //no need to actually cast if you don't need the non-iidentity properties 
     //var identity = (CustomIdentity) this.Context.User.Identity; 
     //identity.Id == 10 
     //identity.Name == "test" 

     return hello; 
    } 

Sinon, au lieu de Global.asax, je suis sûr que vous pourriez le jeter dans le pipeline OWIN après l'authentification de l'utilisateur. Cependant, quelqu'un d'autre aurait besoin de fournir un exemple exact.

EDIT: Juste pour clarifier, j'ai changé le constructeur pour votre CustomIdentity puisque je n'ai pas eu toutes vos classes. Ces exemples ci-dessus ne sont que des preuves de concepts.