2017-05-15 3 views
0

Je travaille sur un site intranet avec l'authentification Windows pour les connexions. Cependant, je souhaite étendre IPrincipal pour avoir d'autres propriétés. Par exemple, je voudrais obtenir le prénom de l'utilisateur dans @User.FirstName ou User.AuthorizedActivity("Admin/Permissions/Edit") (serait récupérer de db) en utilisant des activités au lieu de rôles pour cacher certains liens, etc. J'ai vraiment beaucoup de temps à comprendre cela au cours des 2 dernières années jours et trouver beaucoup d'informations faisant cela avec l'authentification Windows.ASP.NET MVC - Personnalisé IIdentity ou IPrincipal avec l'authentification Windows

Mon CustomPrincipal et la configuration BaseViewPage:

namespace Intranet_v2.Helpers 
{ 
    public interface ICustomPrincipal : IPrincipal 
    { 
     Guid UserGuid { get; set; } 
     string FirstName { get; set; } 
     string LastName { get; set; } 
     string FullName { get; set; } 
    } 

    public class CustomPrincipal : ICustomPrincipal 
    { 
     public IIdentity Identity { get; private set; } 
     public bool IsInRole(string role) { return false; } 

     public CustomPrincipal(string identity) 
     { 
      this.Identity = new GenericIdentity(identity); 
     } 

     public Guid UserGuid { get; set; } 
     public string FirstName { get; set; } 
     public string LastName { get; set; } 
     public string FullName { get; set; } 
    } 

    public class CustomPrincipalSerializeModel 
    { 
     public Guid UserGuid { get; set; } 
     public string FirstName { get; set; } 
     public string LastName { get; set; } 
     public string FullName { get; set; } 
    } 

    public class BaseController : Controller 
    { 
     protected virtual new CustomPrincipal User 
    { 
      get { return HttpContext.User as CustomPrincipal; } 
     } 
    } 

    public abstract class BaseViewPage : WebViewPage 
    { 
     public virtual new CustomPrincipal User 
     { 
      get { return base.User as CustomPrincipal; } 
     } 
    } 

    public abstract class BaseViewPage<TModel> : WebViewPage<TModel> 
    { 
     public virtual new CustomPrincipal User 
     { 
      get { return base.User as CustomPrincipal; } 
     } 
    } 
} 

Vues Web.Config BaseViewPage:

<system.web.webPages.razor> 
<host factoryType="System.Web.Mvc.MvcWebRazorHostFactory, System.Web.Mvc, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" /> 
<pages pageBaseType="Intranet_v2.Helpers.BaseViewPage"> 
    <namespaces> 
    <add namespace="System.Web.Mvc" /> 
    <add namespace="System.Web.Mvc.Ajax" /> 
    <add namespace="System.Web.Mvc.Html" /> 
    <add namespace="System.Web.Optimization"/> 
    <add namespace="System.Web.Routing" /> 
    <add namespace="Intranet_v2" /> 
    </namespaces> 
</pages> 

Je pense que mon principal problème est que je ne sais pas quoi faire dans le protected void Application_PostAuthenticateRequest(object sender, EventArgs args) pour mon fichier Global.asax.cs. J'ai une mauvaise tentative de mise en place ici:

protected void Application_PostAuthenticateRequest(object sender, EventArgs args) 
{ 
    //var application = (HttpApplication)sender; 
    var context = application.Context; 

    if (context.User != null || !context.User.Identity.IsAuthenticated) return; 

    var formsIdentity = (FormsIdentity)context.User.Identity; 

    if (formsIdentity == null) return; 

    var ticket = formsIdentity.Ticket; 


    JavaScriptSerializer serializer = new JavaScriptSerializer(); 

    CustomPrincipalSerializeModel serializeModel = serializer.Deserialize<CustomPrincipalSerializeModel>(ticket.UserData); 

    CustomPrincipal newUser = new CustomPrincipal(ticket.Name); 
    newUser.UserGuid = serializeModel.UserGuid; 
    newUser.FirstName = serializeModel.FirstName; 
    newUser.LastName = serializeModel.LastName; 
    newUser.FullName = serializeModel.FullName; 

    var values = ticket.UserData.Split('|'); 

    var roles = values[1].Split(','); 

    context.User = new GenericPrincipal(new GenericIdentity(ticket.Name, "Forms"), roles); 
} 

Maintenant, je suis au point où @ User.Name est maintenant nulle. Je suis au-dessus de ma tête à ce sujet. Toute aide est appréciée. Mon protected void Application_PostAuthenticateRequest(object sender, EventArgs args) est complètement hors de propos. Tout ce que je veux faire est de compter sur l'authentification Windows pour faire ce qu'elle fait normalement et ajouter quelques propriétés supplémentaires au HttpContext.Current.User. Toute aide est appréciée ... Je ne peux pas être le seul à essayer de le faire.

Répondre

1

Ce que je fais habituellement est de demander l'information additionnelle d'utilisateur plus tard. Par exemple, en utilisant une méthode d'extension comme:

public static class PrincipalExtensions 
{ 
    private static void Initialize(string userName) 
    { 
     var userRecord = //Get user information from DB; 

     var session = HttpContext.Current.Session; 
     if (session != null) 
     { 
     session.Add("UserID", userRecord.ID); 
     session.Add("UserEmail", userRecord.Email); 
     //And so on 
     } 
    } 

    public static long? GetUserID(this IPrincipal user) 
    { 
     var id = HttpContext.Current.Session["UserID"] as long?; 
     if (id == null) 
     Initialize(); 

     return (long)HttpContext.Current.Session["UserID"]; 
    } 
} 

C'est à peu près ce que je mets en œuvre dans certains de mes projets; plutôt que d'exploiter le processus de connexion et de le stocker dans le cookie, le système peut paresser charger l'information et le cache en session lorsque l'information est nécessaire.

+0

Comment puis-je faire fonctionner ceci afin que je puisse accéder à '' GetUserID'' dans une vue, par exemple? Je voudrais cacher certains éléments des utilisateurs qui n'ont pas les permissions correctes. – justiceorjustus

+0

L'idée est que GetUserID() est une méthode d'extension sur IPrincipal, donc dans une vue, vous devez vous assurer que l'espace de noms est disponible afin qu'il puisse voir l'extension. Cela fonctionnera comme 'this.User.GetUserID()'. –

+0

Oui! Il a, en fait, travaillé dans la vue comme il aurait dû l'être à l'origine. J'ai couru dans le "hé, vous avez fait tant de changements majeurs dans votre projet que IntelliSense va être un réflexe" question. Redémarré Visual Studio et il l'a ramassé dans la vue comme prévu. Je vous remercie! – justiceorjustus