2010-12-16 22 views
13

Tengo una aplicación ASP.NET MVC con un controlador que se ve algo como esto:ASP.NET MVC controlador Constructor Llamado antes de la autenticación

[Authorize] 
public class MyController : Controller 
{ 
IMyRepository myRepository; 
public MyController(IMyRepository myRepository) 
{ 
    this.myRepository = myRepository; 
} 

... 
} 

me he dado cuenta de que este constructor es llamado antes de la autenticación del usuario, así que si está visitando la página por primera vez, se llama al constructor antes de redirigirlo a la pantalla de inicio de sesión. Hay muchos problemas con esto, la página de inicio de sesión se carga más despacio, el sitio tiene una mayor exposición a ataques DOS, y estoy un poco nervioso acerca de usuarios no autenticados y no autorizados que pueden invocar el código 'detrás de las paredes'.

Pude comprobar la solicitud entrante en el constructor y fianza a menos que el usuario esté autorizado, pero estoy usando IOC (Windsor), lo que hace que sea un poco complicado, mi repositorio se inicializará independientemente de si almacena la instancia, por lo que me quedaría revisando la autenticación en el constructor de cada repositorio. ¿Hay una manera fácil de obtener .NET MVC para autenticar al usuario anterior para invocar al constructor? Estoy pensando en agregar [PrincipalPermission(SecurityAction.Demand, Authenticated = true)] al controlador, pero aún podría haber una mejor manera.

EDIT:

Ok, no muy feliz por ello, pero el show debe continuar por ahora. No puedo retrasar la inicialización del repositorio hasta algún momento posterior dentro del controlador. Cuando tu controlador usa IOC como en mi ejemplo, obtienes una implementación ya instanciada de tu interfaz de repositorio en el momento en que se crea una instancia del controlador. Si tuviera control sobre el repositorio que se está creando, podría simplemente llamar a IsAuthenticated, sin necesidad de un nuevo método. Para tomar el control de la inicialización del repositorio, debería implementar algún tipo de inicialización diferida/tardía en el repositorio mismo en cada implementación. No me gusta esta solución porque agrega una complejidad innecesaria y, lo que es más importante, un acoplamiento entre el controlador y el repositorio. La (s) implementación (es) del repositorio pueden usarse en otros contextos donde la inicialización lenta no tiene sentido en mi humilde opinión.

+1

Suponiendo que su constructor para su implementación IMyRepository era liviano, entonces no veo un problema importante aquí (es decir, si es un proceso costoso configurar la conexión real a su backing store, hágalo lentamente, es decir, en la primera lectura/escritura) Ya no está más expuesto que con la página de inicio de sesión, ya que eso también es crear instancias de un controlador y, probablemente, acceder a una tienda de respaldo para verificar las credenciales. – Lazarus

+1

@Lazarus Pero, ¿qué pasa si una dependencia en mi controlador requiere acceso a un nombre de usuario no nulo (es decir, el usuario necesita ser autenticado en ese punto). Actualmente estoy usando una instancia 'Lazy ' para eso, pero lo odio. Creo que tendría mucho sentido autenticar al usuario antes de llegar al controlador. – julealgon

Respuesta

0

Paul,

la creación de instancias del controlador es muchos muchos procesos por delante de cualquier acción en el controlador de ser exigible. incluso si el atacante intentara beneficiarse de este lapso de tiempo entre la instanciación y la pantalla de inicio de sesión, la acción del controlador solo se podría ejecutar si la acción tuviera la autoridad para hacerlo, es decir, supongo que sus acciones o controlador tener el atributo [Authorize] en ellos.

No creo que deba preocuparse demasiado por esto y puede estar tranquilo, aunque entiendo su curiosidad obvia.

4

El controlador debe crearse una instancia antes de que se produzca la autorización, ya que puede actuar como su propio filtro de autorización a través del método OnAuthorization. Cambiar ese comportamiento implicaría reemplazar algunas partes centrales de la tubería de mvc. ¿Hay alguna razón en particular por la que piensas que el AuthorizedAttribute podría no hacer su trabajo?

+0

Mis controladores tienen constructores bastante pesados, y no quiero que usuarios no autenticados puedan iniciar el código. Entiendo que la autorización no puede ocurrir antes de que el controlador sea instanciado, solo quiero que la autenticación se realice de antemano. Publicaré lo que encuentre aquí cuando termine. – Paul

+0

Ah, si solo quiere evitar que los usuarios no autentificados lleguen siquiera a su controlador, entonces podría buscar escribir una ruta personalizada que no coincida con los clientes no autenticados. – marcind

+2

Otra opción que podría considerar es inicializar su repositorio en OnActionExecuting de su método de controlador en lugar de hacerlo en el constructor. – marcind

0

En términos de ataques DOS, realmente no debería importar - después del primer golpe, que se ve mucho cuando se desarrolla, la instanciación del controlador debe ser barata. Bueno, a menos que esté DDOSing usted mismo haciendo que el constructor haga un trabajo real, como las búsquedas en la base de datos de precaching. . .

Cuestiones relacionadas