Custom Principal

Discussion in 'ASP .Net' started by David B. Bitton, Feb 25, 2004.

  1. For some odd reason, despite the fact that I assign my own custom IPrincipal
    to the HttpContext.User property in an HttpApplication.AuthenticateRequest

    event handler inside of an IHttpModule, when I check the Page.User property,
    it's a WindowsPrincipal and not _my_ custom Iprincipal. Why would this be?

    ....

    using System;

    using System.Web;

    using System.Security.Principal;

    namespace ImpersonationSample

    {

    /// <summary>

    /// Summary description for AuthenticationModule.

    /// </summary>

    public class AuthenticationModule : IHttpModule

    {

    private IPrincipal contextUser;

    public AuthenticationModule()

    {

    //

    // TODO: Add constructor logic here

    //

    }

    #region IHttpModule Members

    public void Init(HttpApplication context)

    {

    context.AuthenticateRequest +=

    new

    EventHandler(context_AuthenticateRequest);

    }

    public void Dispose()

    {

    // TODO: Add AuthenticationModule.Dispose implementation

    }

    #endregion

    private void context_AuthenticateRequest(object sender, EventArgs e)

    {

    HttpApplication application = (HttpApplication)sender;

    HttpContext context = application.Context;

    HttpRequest request = context.Request;

    HttpResponse response = context.Response;

    contextUser = context.User;

    if(request.IsAuthenticated)

    {

    /**

    * If the calling user is authenticated via NTLM by

    * IIS, then we can derive Windows user info.

    **/

    // create our own custom User object

    CustomUser user = new CustomUser(contextUser.Identity.Name);

    // assign _our_ IPrincipal to the current request.

    contextUser = new CustomPrincipal(contextUser.Identity, user);;

    }

    }

    }

    }

    using System;

    using System.Security.Principal;

    namespace ImpersonationSample

    {

    /// <summary>

    /// Summary description for CustomPrincipal.

    /// </summary>

    public class CustomPrincipal : IPrincipal

    {

    private IIdentity identity;

    private CustomUser user;

    public CustomPrincipal(IIdentity identity, CustomUser user)

    {

    this.identity = identity;

    this.user = user;

    }

    public IIdentity Identity

    {

    get{ return identity; }

    }

    public string Username

    {

    get{ return user.Username; }

    }

    public bool IsInRole(string role)

    {

    return true;

    }

    }

    }

    using System;

    namespace ImpersonationSample

    {

    /// <summary>

    /// Summary description for CustomUser.

    /// </summary>

    public class CustomUser

    {

    private string name;

    public CustomUser(string username)

    {

    this.name = username.Split('\\')[1];

    }

    public string Username

    {

    get{ return Username; }

    }

    }

    }

    ....

    private void Page_Load(object sender, System.EventArgs e)

    {

    if(!IsPostBack)

    UsernameLabel.Text = ((CustomPrincipal)HttpContext.Current.User).Username;

    }

    ....


    --
    --

    David B. Bitton

    www.codenoevil.com

    Code Made Fresh DailyT
     
    David B. Bitton, Feb 25, 2004
    #1
    1. Advertising

  2. Hi David,


    Thanks for posting in the community!
    From your description, you have a custom Principal class and in the
    HttpModule's Application_AuthenticateRequest event, you used it to replace
    the original IPrincipal in the HttpContext.Current.User . However, you
    found you can't retrieve it back again later, yes?

    I've made a smiple Application use "windows" authentication and tried your
    code, I made the operations in Global object instead of a HttpModule( I
    think they will perform the same). What I found is that there seems to be a
    small mistake in the "CustomUser" class, it is focus on the "Username"
    property, you code is as below:
    public string Username
    {
    get{ return Username; }
    }

    that causes the property be recursively called and stack overflow. After I
    correct the code and test again, it seems work fine on my side. So would
    you please have a further check on it to see whether this cause the
    problem? And here is my code used to test:
    -----------------in global object-----------------
    protected void Application_AuthenticateRequest(Object sender, EventArgs e)
    {
    HttpApplication application = (HttpApplication)sender;

    HttpContext context = application.Context;
    HttpRequest request = context.Request;
    HttpResponse response = context.Response;


    if(request.IsAuthenticated)
    {
    CustomUser user = new CustomUser(context.User.Identity.Name);
    context.User = new CustomPrincipal(context.User.Identity, user);;
    }

    }
    -----------------------------------in page's
    page_load-------------------------------
    private void Page_Load(object sender, System.EventArgs e)
    {
    CustomPrincipal cp = (CustomPrincipal)HttpContext.Current.User;

    Response.Write("<br>" + HttpContext.Current.User.GetType().ToString() );
    Response.Write("<br>" + cp.Username );

    }


    If you still feel meet the problem or have anything else unclear, please
    feel free to post here.



    Regards,

    Steven Cheng
    Microsoft Online Support

    Get Secure! www.microsoft.com/security
    (This posting is provided "AS IS", with no warranties, and confers no
    rights.)

    Get Preview at ASP.NET whidbey
    http://msdn.microsoft.com/asp.net/whidbey/default.aspx
     
    Steven Cheng[MSFT], Feb 26, 2004
    #2
    1. Advertising

  3. Steven,
    I found the same error last night w/ the property accessor in the
    CustomUser class. Furthermore, I also moved my code into the Global.asax
    file, and yes, it worked. My question is this, why doesn't this work from
    within an HttpModule? Is there other intrinsic HttpModules that are called
    _after_ mine that essentially reset the IPrincipal?

    --
    --

    David B. Bitton

    www.codenoevil.com

    Code Made Fresh Daily™
    "Steven Cheng[MSFT]" <> wrote in message
    news:zsRJS0C$...
    > Hi David,
    >
    >
    > Thanks for posting in the community!
    > From your description, you have a custom Principal class and in the
    > HttpModule's Application_AuthenticateRequest event, you used it to replace
    > the original IPrincipal in the HttpContext.Current.User . However, you
    > found you can't retrieve it back again later, yes?
    >
    > I've made a smiple Application use "windows" authentication and tried your
    > code, I made the operations in Global object instead of a HttpModule( I
    > think they will perform the same). What I found is that there seems to be

    a
    > small mistake in the "CustomUser" class, it is focus on the "Username"
    > property, you code is as below:
    > public string Username
    > {
    > get{ return Username; }
    > }
    >
    > that causes the property be recursively called and stack overflow. After I
    > correct the code and test again, it seems work fine on my side. So would
    > you please have a further check on it to see whether this cause the
    > problem? And here is my code used to test:
    > -----------------in global object-----------------
    > protected void Application_AuthenticateRequest(Object sender, EventArgs e)
    > {
    > HttpApplication application = (HttpApplication)sender;
    >
    > HttpContext context = application.Context;
    > HttpRequest request = context.Request;
    > HttpResponse response = context.Response;
    >
    >
    > if(request.IsAuthenticated)
    > {
    > CustomUser user = new CustomUser(context.User.Identity.Name);
    > context.User = new CustomPrincipal(context.User.Identity, user);;
    > }
    >
    > }
    > -----------------------------------in page's
    > page_load-------------------------------
    > private void Page_Load(object sender, System.EventArgs e)
    > {
    > CustomPrincipal cp = (CustomPrincipal)HttpContext.Current.User;
    >
    > Response.Write("<br>" + HttpContext.Current.User.GetType().ToString() );
    > Response.Write("<br>" + cp.Username );
    >
    > }
    >
    >
    > If you still feel meet the problem or have anything else unclear, please
    > feel free to post here.
    >
    >
    >
    > Regards,
    >
    > Steven Cheng
    > Microsoft Online Support
    >
    > Get Secure! www.microsoft.com/security
    > (This posting is provided "AS IS", with no warranties, and confers no
    > rights.)
    >
    > Get Preview at ASP.NET whidbey
    > http://msdn.microsoft.com/asp.net/whidbey/default.aspx
    >
     
    David B. Bitton, Feb 26, 2004
    #3
  4. Hi David,

    Thanks for your followup. Regarding on your further description, I've done
    a test using the HttpModule on my side. It seems the HttpModule can also
    work just as in the Global object. I've also added some break point and
    debug , the call sequence is as:
    1. Application_BeginRequest in HttpModule
    2. Application_AuthenticateRequest in httpModule
    3. Application_AuthenticateRequest in Global object

    And here is the code I used in my tests:
    ---------------------httpModule----------------------------
    public class SecurityHttpModule : IHttpModule
    {

    public void Init(HttpApplication application)
    {
    application.BeginRequest += (new
    EventHandler(this.Application_BeginRequest));
    application.AuthenticateRequest += new
    EventHandler(Application_AuthenticateRequest);
    }

    private void Application_BeginRequest(Object source, EventArgs e)
    {
    HttpApplication application = (HttpApplication)source;

    HttpContext context = application.Context;

    context.Response.Write("<br>This request is begined" +
    DateTime.Now.ToLongTimeString());

    }

    protected void Application_AuthenticateRequest(Object source, EventArgs e)
    {
    HttpApplication application = (HttpApplication)source;

    HttpContext context = application.Context;

    HttpRequest request = context.Request;

    HttpResponse response = context.Response;

    context.User = context.User;

    if(request.IsAuthenticated)
    {

    CustomUser user = new CustomUser(context.User.Identity.Name);

    context.User = new CustomPrincipal(context.User.Identity, user);
    context.Response.Write("<br>This request is authenticated! in
    httpmodule" + DateTime.Now.ToLongTimeString());

    }

    }

    public void Dispose() {}
    }

    -----------------------test page's page load----------------------
    private void Page_Load(object sender, System.EventArgs e)
    {
    CustomPrincipal cp = (CustomPrincipal)HttpContext.Current.User;

    Response.Write("<br>" + HttpContext.Current.User.GetType().ToString() );
    Response.Write("<br>" + cp.Username );
    }

    -------------------------------web.config setting--------------------------
    <configuration>
    <system.web>
    <authentication mode="Windows" />
    .............
    <httpModules>
    <add name="SecurityHttpModule"
    type="WebApplication1.SecurityHttpModule,
    WebApplication1" />
    </httpModules>
    </system.web>
    </configuration>

    ==================================

    Please check out my test codes to see whether it can provide any clues on
    this issue. Also, I think you may add some break points in code to trace
    the request. And using some "Response.Write" to append some info such as:
    context.Response.Write("<br>This request is authenticated! in httpmodule" +
    DateTime.Now.ToLongTimeString());
    will also be helpful to troubleshoot.

    If you have anything unclear, please feel free to post here.


    Regards,

    Steven Cheng
    Microsoft Online Support

    Get Secure! www.microsoft.com/security
    (This posting is provided "AS IS", with no warranties, and confers no
    rights.)

    Get Preview at ASP.NET whidbey
    http://msdn.microsoft.com/asp.net/whidbey/default.aspx
     
    Steven Cheng[MSFT], Feb 27, 2004
    #4
  5. Hi Localhost,

    Have you had a chance to check out my suggestions or have you got any other
    ideas on this issue?
    If you have any further questions, please feel free to post here.


    Regards,

    Steven Cheng
    Microsoft Online Support

    Get Secure! www.microsoft.com/security
    (This posting is provided "AS IS", with no warranties, and confers no
    rights.)

    Get Preview at ASP.NET whidbey
    http://msdn.microsoft.com/asp.net/whidbey/default.aspx
     
    Steven Cheng[MSFT], Mar 2, 2004
    #5
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. lucd
    Replies:
    2
    Views:
    4,819
  2. padma
    Replies:
    3
    Views:
    431
    Victor Bazarov
    Oct 5, 2007
  3. Eric Wise

    Custom Windows Authentication Principal?

    Eric Wise, Feb 10, 2004, in forum: ASP .Net Security
    Replies:
    1
    Views:
    174
    Joe Kaplan \(MVP - ADSI\)
    Feb 10, 2004
  4. Custom Principal

    , Feb 24, 2005, in forum: ASP .Net Security
    Replies:
    0
    Views:
    128
  5. Michael
    Replies:
    3
    Views:
    223
    Jerry Goldin
    May 12, 2004
Loading...

Share This Page