简体   繁体   中英

ASP.NET Core Identify Auth + Angular: Login Not Working

I'm presently developing an application with an ASP.NET Core (2.1) API server/backend and an Angular Single Page Application frontend.

For user authentication, I'm using ASP.NET Core Identity, along with several of the default methods provided within AccountController for login, logout, register, forgot password, etc. My Angular application accesses this API to perform these actions.

The Angular client files are hosted directly out of wwwroot in the ASP.NET Core application. I am hosting using IIS Express (I have tried IIS as well to no avail) under localhost:5000 .

Authentication is configured in ASP.NET Core's Startup class with the following:

services.AddIdentity<ApplicationUser, IdentityRole>(config =>
    {
        config.SignIn.RequireConfirmedEmail = false;
        config.Password.RequiredLength = 8;
    })
    .AddEntityFrameworkStores<AppDbContext>()
    .AddDefaultTokenProviders();

// Prevent API from redirecting to login or Access Denied screens (Angular handles these).
services.ConfigureApplicationCookie(options =>
{
    options.Events.OnRedirectToLogin = context =>
    {
        context.Response.StatusCode = 401;
        return Task.CompletedTask;
    };
    options.Events.OnRedirectToAccessDenied = context =>
    {
        context.Response.StatusCode = 403;
        return Task.CompletedTask;
    };
});

Register and Forgot Password both work without a hitch. The API is called and the appropriate actions are taken.

Login appears to work: The method is invoked within Angular:

@Injectable()
export class AuthService extends BaseService {
  constructor(private httpClient: HttpClient) {
    super(httpClient, `${config.SERVER_API_URL}/account`);
  }

  // Snip

  login(login: Login): Observable<boolean> {
    return this.httpClient.post<boolean>(`${this.actionUrl}/Login`, login)
      .catch(this.handleError);
  }

  // Snip
}

The ASP.NET Core API gets the call, logs the user in, and returns success to indicate to Angular that login worked and they should proceed to redirect the user:

namespace ApartmentBonds.Web.Api.Account
{
    [Route("api/[controller]/[action]")]
    public class AccountController : APIControllerBase
    {
        // Snip

        [HttpPost]
        [AllowAnonymous]
        public async Task<IActionResult> Login([FromBody] LoginViewModel model, string returnUrl = null)
        {
            await HttpContext.SignOutAsync(IdentityConstants.ExternalScheme);

            ViewData["ReturnUrl"] = returnUrl;
            if (ModelState.IsValid)
            {
                var result = await _signInManager.PasswordSignInAsync(model.Username, model.Password, model.RememberMe, false);
                if (result.Succeeded)
                {
                    _logger.LogInformation("User logged in.");
                    return Ok(true);
                }
            }

            return Ok(false);
        }

        // Snip
    }
}

The session cookie is created successfully, and I can see it within the browser (using Firefox Quantum in this screenshot, but have also tried in IE, in Firefox incognito, etc):

曲奇饼

To test, I have another API method which simply returns whether or not the calling user is signed in:

// Angular
isLoggedIn(): Observable<boolean> {
  return this.httpClient.get<boolean>(`${this.actionUrl}/IsLoggedIn`)
    .catch(this.handleError);
}

// ASP.NET Core API
[HttpGet]
[AllowAnonymous]
public IActionResult IsLoggedIn()
{
    return Ok(_signInManager.IsSignedIn(User));
}

I make this call within the browser, and it returns false . (All other aspects of the site that depend on the user being logged in also show the user is not logged in -- this method is just a quick and dirty way to verify this problem.) Note that the client is correctly sending the Identity cookie along with the request:

IsLoggedIn请求

Since the only site in question here is localhost:5000 I'm not sure why this is not working.

Things I've tried

  • Within services.ConfigureApplicationCookie
    • Setting options.Events.Cookie.Domain to localhost:5000 explicitly
    • Setting options.Events.Cookie.Path to /api
  • Clearing all cookies and trying incognito/other browsers (to rule out other localhost site cookies potentially clobbering the request)
  • Hosting the site via IIS ( localhost:8888 ) after Publishing the Core Application

Anyone have any ideas?

In order for authentication handlers to run on the request, you need app.UseAuthentication(); in the middleware pipeline (before middleware that requires it like MVC).

这是一个远景,但也许令牌需要:“持票人”(带空格)在实际令牌前面。

I think you shouldn't use User property from controller when you are using AllowAnonymousAttribute .

Try to do request to some authorize endpoint. If you are not sign in, then you will get status code 401(Unathorized).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM