User.Identity.Name为null

时间:2017-06-01 09:21:44

标签: authentication asp.net-core-mvc auth0

我有一个用ASP .Net Core 1.1 MVC编写的Web应用程序。我使用Auth0作为身份验证服务器。成功登录后,“索引”页面应显示登录用户的姓名,但不是。如果我查看我的_Layout.cshtml视图:

@if (User.Identity.IsAuthenticated)
{
    <li><a asp-controller="Account" asp-action="Profile">Hello @User.Identity.Name!</a></li>
    <li><a asp-controller="Account" asp-action="Logout">Logout</a></li>
}
else
{
    <li><a asp-controller="Account" asp-action="Login"  asp-route-returnUrl="@Url.Action("Index", "Home")'">Login</a></li>
}

@ User.Identity.Name 为空。但是因为我对ASP和身份验证都很陌生,所以我很难弄明白为什么......

我关注的一件事情,我不知道它是否可能是相关的,是在用户登录后,他被重定向到错误的地方(而不是重定向到主页或类似的东西(http://localhost:60856/),它会重定向到http://localhost:60856/&#39; 你可以看到最后有一个撇号,我不知道为什么会发生这种情况,如果这与任何事情有关......

这是我的Startup.cs文件(抱歉,它已经很长了!)

public class Startup
{
    public IConfigurationRoot Configuration { get; }
    public IHostingEnvironment HostingEnvironment { get; }

    public Startup(IHostingEnvironment env)
    {
        var builder = new ConfigurationBuilder()
            .SetBasePath(env.ContentRootPath)
            .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
            .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true);

        if (env.IsDevelopment())
            builder.AddUserSecrets<Startup>();

        builder.AddEnvironmentVariables();
        Configuration = builder.Build();

        HostingEnvironment = env;
    }

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddAuthentication(
            options => options.SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme);

        services.AddMvc();

        services.AddOptions();

        services.Configure<Auth0Settings>(Configuration.GetSection("Auth0"));
    }

    public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory, IOptions<Auth0Settings> auth0Settings)
    {
        loggerFactory.AddConsole(Configuration.GetSection("Logging"));
        loggerFactory.AddDebug();

        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
            app.UseBrowserLink();
        }
        else
        {
            app.UseExceptionHandler("/Home/Error");
        }

        app.UseStaticFiles();

        // Add the cookie middleware
        app.UseCookieAuthentication(new CookieAuthenticationOptions
        {
            AutomaticAuthenticate = true,
            AutomaticChallenge = true,

            Events = new CookieAuthenticationEvents()
            {

                OnRedirectToLogin = ctx =>
                {
                    // if it is an ajax / api request, don't redirect to login page.
                    if (!(IsAjaxRequest(ctx.Request) || IsApiRequest(ctx.Request)))
                    {
                        ctx.Response.Redirect(ctx.RedirectUri);
                        return Task.CompletedTask;
                    }
                    ctx.Response.StatusCode = StatusCodes.Status401Unauthorized;
                    return ctx.Response.WriteAsync("Unauthorized");
                }
            }
        });

        // Add the OIDC middleware
        var options = new OpenIdConnectOptions("Auth0")
        {
            // Set the authority to your Auth0 domain
            Authority = $"https://{auth0Settings.Value.Domain}",

            // Configure the Auth0 Client ID and Client Secret
            ClientId = auth0Settings.Value.ClientId,
            ClientSecret = auth0Settings.Value.ClientSecret,

            // Do not automatically authenticate and challenge
            AutomaticAuthenticate = false,
            AutomaticChallenge = false,

            // Set response type to code
            ResponseType = OpenIdConnectResponseType.Code,

            // Set the callback path, so Auth0 will call back to http://localhost:5000/signin-auth0 
            // Also ensure that you have added the URL as an Allowed Callback URL in your Auth0 dashboard 
            CallbackPath = new PathString("/signin-auth0"),
            //CallbackPath = new PathString("/signin-auth0"),

            // Configure the Claims Issuer to be Auth0
            ClaimsIssuer = "Auth0",

            // The UserInfo endpoint does not really return any extra claims which were not returned in the original auth response, so
            // we can save ourselves from making an extra request
            GetClaimsFromUserInfoEndpoint = false,

            // Saves tokens to the AuthenticationProperties
            SaveTokens = true,

            Events = new OpenIdConnectEvents
            {
                OnTicketReceived = context =>
                {
                    // Get the ClaimsIdentity
                    var identity = context.Principal.Identity as ClaimsIdentity;
                    if (identity != null)
                    {
                            // Add the Name ClaimType. This is required if we want User.Identity.Name to actually return something!
                            if (!context.Principal.HasClaim(c => c.Type == ClaimTypes.Name) &&
                            identity.HasClaim(c => c.Type == "name"))
                            identity.AddClaim(new Claim(ClaimTypes.Name, identity.FindFirst("name").Value));

                            // Check if token names are stored in Properties
                            if (context.Properties.Items.ContainsKey(".TokenNames"))
                            {   
                                // Token names a semicolon separated
                                string[] tokenNames = context.Properties.Items[".TokenNames"].Split(';');

                                // Add each token value as Claim
                                foreach (var tokenName in tokenNames)
                                {
                                    // Tokens are stored in a Dictionary with the Key ".Token.<token name>"
                                    string tokenValue = context.Properties.Items[$".Token.{tokenName}"];
                                    identity.AddClaim(new Claim(tokenName, tokenValue));
                                }
                            }
                    }

                    return Task.CompletedTask;
                },

                OnRedirectToIdentityProvider = context =>
                {
                    context.ProtocolMessage.Parameters.Add("audience", auth0Settings.Value.ApiIdentifier);
                    return Task.CompletedTask;
                },
                //handle the logout redirection
                OnRedirectToIdentityProviderForSignOut = (context) =>
                {
                    var logoutUri = $"https://{auth0Settings.Value.Domain}/v2/logout?client_id={auth0Settings.Value.ClientId}";

                    var postLogoutUri = context.Properties.RedirectUri;
                    if (!string.IsNullOrEmpty(postLogoutUri))
                    {
                        if (postLogoutUri.StartsWith("/"))
                        {
                            // transform to absolute
                            var request = context.Request;
                            postLogoutUri = request.Scheme + "://" + request.Host + request.PathBase + postLogoutUri;
                        }
                        logoutUri += $"&returnTo={ Uri.EscapeDataString(postLogoutUri)}";
                    }

                    context.Response.Redirect(logoutUri);
                    context.HandleResponse();

                    return Task.CompletedTask;
                }
           },
        };

        options.Scope.Clear();
        options.Scope.Add("openid");
        options.Scope.Add("name");
        options.Scope.Add("email");
        options.Scope.Add("picture");
        options.Scope.Add("country");
        options.Scope.Add("roles");
        app.UseOpenIdConnectAuthentication(options);

        app.UseMvc(routes =>
        {
            routes.MapRoute(
                name: "default",
                template: "{controller=Home}/{action=Index}/{id?}");
        });
    }

    private static bool IsAjaxRequest(HttpRequest request)
    {
        var query = request.Query;
        if ((query != null) && (query["X-Requested-With"] == "XMLHttpRequest"))
        {
            return true;
        }
        IHeaderDictionary headers = request.Headers;
        return ((headers != null) && (headers["X-Requested-With"] == "XMLHttpRequest"));
    }

    private static bool IsApiRequest(HttpRequest request)
    {

        return request.Path.StartsWithSegments(new PathString("/api"));
    }
}

有什么想法吗?

1 个答案:

答案 0 :(得分:1)

我切换到使用oauth2而不是openid,这解决了我的问题。所以我的startup.cs文件现在看起来很像样本:

https://github.com/auth0-samples/auth0-aspnetcore-mvc-samples/blob/master/Samples/oauth2/Startup.cs