How to get PrincipalInfo in web api?

Vote:
 

Hi!

I have a site which is built on AspNet Identity, and I would like to have an api method (not using Headless) that returns logged in status for the current user.

Is this possible?

It looks like this:

As you can see, I get Name " " and only the "Everyone" and "Anonymous" role, even thought the user is logged in.

#208572
Edited, Oct 28, 2019 13:15
Vote:
 

Do you have code to supress the cookie authentication in ApiController? or do you have ServiceAPI installed?

#208603
Oct 28, 2019 18:39
Vote:
 

Hi Torunn

As I recall, this can happen if the authenication middleware doesn't execute correctly on the WebAPI request pipeline.

Do you have the following line at the end of your OWIN Startup class?

app.UseStageMarker(PipelineStage.Authenticate);

I don't recall if that fixed the same or another of the authentication issues I have faced with WebAPI on Episerver.

#208617
Oct 28, 2019 19:13
Vote:
 

Stefan: This didn't do any difference, unfortunately.

Quan: No, I don't have the ServiceApi installed. I don't think I have code to supress the cookie authentication. I have the same configuration in startup.cs as in Alloy, although i have some custom configuration:

#208626
Edited, Oct 29, 2019 8:20
Vote:
 

Can try this in a IConfigurableModule's ConfigureContainer(ServiceConfigurationContext context)

GlobalConfiguration.Configure(config =>
{
    config.Filters.Add(new HostAuthenticationFilter(DefaultAuthenticationTypes.ApplicationCookie));
});

Not sure if it will work for you, but worked for me (but we allso use epis default app.AddCmsAspNetIdentity<ApplicationUser>(); ​)

Edit: had a little too much info there :)

#208751
Edited, Oct 31, 2019 12:00
inmeta_ts - Oct 31, 2019 14:57
What does you HostAuthenticationFilter look like?
Sebastian Enberget - Oct 31, 2019 18:42
Ah, sorry. It should be in the owin package: Microsoft.AspNet.WebApi.Owin
The namespace (as fare as I can see is this: System.Web.Http
Vote:
 

So I added this line

config.Filters.Add(new HostAuthenticationFilter(DefaultAuthenticationTypes.ApplicationCookie));

at the end of my 

GlobalConfiguration.Configure(config =>

in Application_Start method in Global.asax.cs. But PrincipalInfo is still returning anonymous.

#208777
Edited, Nov 01, 2019 8:54
Vote:
 

Wonder if that maybe is too early, and it also may not be the issue... but we try everything :)

namespace Norrona.Commerce.Site.Infrastructure.Initialization
{
    [ModuleDependency(typeof(EPiServer.Commerce.Initialization.InitializationModule))]
    public class TestInitialization : IConfigurableModule
    {
        public void Initialize(InitializationEngine context)
        {
            
        }

        public void ConfigureContainer(ServiceConfigurationContext context)
        {
            GlobalConfiguration.Configure(config =>
            {
                config.Filters.Add(new HostAuthenticationFilter(DefaultAuthenticationTypes.ApplicationCookie));
            });

        }
        
        public void Uninitialize(InitializationEngine context) { }
    }
}

This is a very stripped down of my initialization for the site

Oh and you use the cookie authenticatior? Would be a good first question

I have this in my startup.cs (I also use epis default AddCmsAspNetIdentity<SiteUser>() (SiteUser is a class in my solution)

In the startup.cs, right after the AddCmsAspNetIdentity I have this:

app.UseCookieAuthentication(new CookieAuthenticationOptions
            {
                AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
                LoginPath = new PathString("/Login"),
                Provider = new CookieAuthenticationProvider
                {
                    // Enables the application to validate the security stamp when the user logs in.
                    // This is a security feature which is used when you change a password or add an external login to your account.  
                    OnValidateIdentity = SecurityStampValidator.OnValidateIdentity<ApplicationUserManager<SiteUser>, SiteUser>(
                        validateInterval: TimeSpan.FromMinutes(30),
                        regenerateIdentity: (manager, user) => manager.GenerateUserIdentityAsync(user)),
                    OnApplyRedirect = (context => context.Response.Redirect(context.RedirectUri)),
                    //OnResponseSignOut = (context => context.Response.Redirect(UrlResolver.Current.GetUrl(ContentReference.StartPage)))
                }
            });

#208780
Nov 01, 2019 9:44
Vote:
 

Yes, I use the cookie authenticator, and I tried stripping down my startup.cs to the cookieauthentication code you posted above, and changed to default AddCmsAspNetIdentity, but still no luck... what am I missing? 

#208784
Nov 01, 2019 12:19
Vote:
 

Hi Torunn,

It also matters how you call your API from client - meaning are you actually even passing any "credentials" to the call to the API?

#208831
Nov 03, 2019 18:06
Vote:
 

Hi Antti,

that's the thing I am unsure about. It's just a call to the api from frontend, where we would like to make a simple check in the backend, whether the current user is logged in or not. If this is not possible, how should the front end developer call this api? We are trying to avoid sending e.g. username.

#208853
Nov 04, 2019 10:46
Vote:
 

We use webapi in our solution, and in the frontend we just do a regular Ajax call to the webapi. Since it is the same domain, then the auth cookie that asp.bet use should be sent too in that call automatic.

So if the frontend code doesn't send ".AspNet.ApplicationCookie" to the api call, then the principal will be empty, but like I said, this usually happens automatic

#209068
Nov 07, 2019 6:45
Vote:
 

Hi Torunn,

In debug mode check the "Cookie" header value (so for example in the immediate window: Request.Headers.GetValues("Cookie"); )

Do you get any cookies in the request?

For example you could also just create a new Alloy site, add Web API, create a demo Web Api controller and then try with that - and compare to your solution.

I just did a demo with Alloy and Web API, and I don't need to do anything special in the Ajax call and I can check the user in my Web API controller.

As Sebbe also pointed out, if your front-end and Web API are in the same domain it should just work BUT if your front-end is in other domain than your Episerver site, then your authentication cookie is not sent from the front-end - so how is your setup?

#209129
Nov 07, 2019 21:57
Vote:
 

Edit: this was on a solution which don't use the Identity provider, but it may apply still

Started a new job, and they had the same issue. Turned out they had this line

config.SuppressHostPrincipal();

in their code, which removes the authentication.

Then we also needed to add this filter

config.Filters.Add(new AuthorizeAttribute());

(this line is only needed if you use the [Authorize] attribute

After adding that line, things started working as expected

#220533
Edited, Apr 02, 2020 7:13
* You are NOT allowed to include any hyperlinks in the post because your account hasn't associated to your company. User profile should be updated.