En mi primera exposición a Angular, tengo una aplicación existente que usa una interfaz de Angular y una API web de .NET para el backend. La aplicación preexistente utilizaba un esquema de inicio de sesión con cuentas locales almacenadas en la base de datos. Estoy intentando modificar esta aplicación para usar el servidor CAS de nuestra organización para la autenticación.
El trabajo que he hecho hasta ahora se basó en la guía que se encuentra aquí: https://www.blinkingcaret.com/2018/10/10/sign-in-with-an-external-login-provider-in-an-angular -aplicación-servida-por-asp-net-core/
Hasta ahora, he realizado algunos cambios clave. En authentication.service.ts, modifiqué la función de inicio de sesión para señalar mi nueva acción en el servidor
login(){ this.document.location.href = this.casUrl + "login" }En mi controlador CAS recién agregado, tengo las siguientes acciones.
public ActionResult Login() { return new ChallengeResult("CAS"); } public ActionResult HandleLogin() { var claimsId = (ClaimsIdentity)User.Identity; //Do things with claims, check against DB, etc } private class ChallengeResult : HttpUnauthorizedResult { //sets the RedirectUri to HandleLogin, fires the Challenge in the ExecuteResult function }Hasta este punto, las cosas parecen estar funcionando. User.Identity se completa correctamente, por lo que puedo recuperar el usuario correspondiente de la base de datos. También puedo construir un objeto LoginResponse, aunque actualmente no estoy haciendo nada con él. Esta respuesta de inicio de sesión incluye un token generado en otra parte de la aplicación y parece ser un JWT.
En este punto, no sé cómo transferir mi LoginResponse de nuevo a Angular.
En la implementación original con cuentas locales, se realizaba una publicación en un extremo de la API y la respuesta se canalizaba a donde se necesitaba.
return this.http.post(this.apiUrl + 'auth/login', //parameters ), headers).pipe( map((user:LoginResponse) => { //do stuff with LoginResponse }));A su vez, el componente que llamó a este servicio está suscrito a su valor de retorno.
Mi idea era tener una nueva función llamada dentro del inicio de un componente. La primera acción que tomaría sería ir a mi punto final CasUrl y solicitar la LoginResponse construida usando User.Identity y DB lookup. Desafortunadamente, la Identidad está vacía en todas las llamadas posteriores al servidor. No parece persistir entre solicitudes.
Una nota más que puede ser relevante: mi solución Web API se ejecuta a través de Visual Studio en localhost:46000, mientras que la aplicación Angular se ejecuta en VSCode en localhost:4200.
¿Qué me falta para que la autenticación externa funcione con esta aplicación? ¿Es posible tener una tubería angular o suscribirse esperar los resultados de un sitio web externo?
Si lo entiendo correctamente, realiza una redirección completa a su servidor CAS con location.href que hace (después de una autenticación exitosa) una redirección a su ruta/inicio de sesión. Por lo tanto, /login debería responder con el sitio angular completo o redirigir al sitio con HttpStatus 302. La cookie de sesión generada por el servidor se puede usar para más solicitudes al backend. AccountService.ts puede verificar si el usuario está autenticado llamando a la API api/home/isAuthenticated Esta solicitud debe agregar automáticamente la cookie de sesión recién recopilada.
vea el código de ejemplo del blog que mencionó: https://github.com/ruidfigueiredo/angular-aspnetcore-external-login/blob/master/AngularWithGoogleLogin/src/app/account.service.ts#:~:text=%20updateuserauthenticationstatus
La respuesta de Stef es esencialmente lo que se requería. Descubrí que la cookie de sesión se estaba creando y almacenando correctamente en el navegador, aunque estaba acostumbrado a que el backend mantuviera automáticamente el estado de la sesión.
Agregué una llamada a la API para verificar el estado de inicio de sesión y, como se indica en la pregunta, el valor User.Identity estaba vacío.
Lo que elegí hacer fue crear el objeto LoginResponse y asignar su valor a una cookie. Luego, en la función de inicio del componente, verificaría la cookie en lugar de llamar a la API.