2009-08-24 22 views
16

Estoy intentando integrar Spring Security en mi aplicación web. Parece bastante fácil hacerlo siempre que integre todo el proceso de autenticación y autorización.spring-security: autorización sin autenticación

Sin embargo, tanto la autenticación como la autorización parecen estar tan acopladas que me lleva mucho tiempo entender cómo podría dividir estos procesos y obtener autenticación independientemente de la autorización.

El proceso de autenticación es externo a nuestro sistema (basado en el inicio de sesión único) y no se puede modificar. Sin embargo, una vez que el usuario tiene éxito en este proceso, se carga en la sesión, incluidos los roles.

Lo que estamos tratando de lograr es utilizar esta información para el proceso de autorización de Spring Security, es decir, forzarla a obtener los roles de la sesión del usuario en lugar de recogerla a través del proveedor de autenticación .

¿Hay alguna manera de lograr esto?

+0

Actualicé mi respuesta. –

Respuesta

18

Si su autenticación ya está hecha usando un servicio SSO, entonces debe usar uno de los pre-authentication filters de Spring Security. A continuación, puede especificar un servicio DetallesUsuario (posiblemente personalizado) que va a utilizar el principio de usuario previamente autenticado para poblar de la GrantedAuthority

SpringSecurity incluye varios filtros de pre-autenticación, incluyendo J2eePreAuthenticatedProcessingFilter y RequestHeaderPreAuthenticatedProcessingFilter. Si no puede encontrar uno que funcione para usted, también es posible, y no tan difícil de escribir, siempre que sepa en qué parte de la solicitud su implementación de SSO contiene los datos. (Eso depende de la aplicación, por supuesto.)

Sólo implementar la interfaz Filter y hacer algo como esto en el método doFilter:

public void doFilter(ServletRequest request, ServletResponse response, 
      FilterChain chain) throws IOException, ServletException { 

    // principal is set in here as a header or parameter. you need to find out 
    // what it's named to extract it 
    HttpServletRequest req = (HttpServletRequest) request; 

    if (SecurityContextHolder.getContext().getAuthentication() == null) { 
     // in here, get your principal, and populate the auth object with 
     // the right authorities 
     Authentication auth = doAuthentication(req); 
     SecurityContextHolder.getContext().setAuthentication(auth); 
    } 

    chain.doFilter(request, response); 
} 
+0

hi Nont, he estado trabajando en esto. Su respuesta es muy útil, aunque ahora tengo que posponer este problema por unos días. Volveré y le contaré cómo van las cosas. ¡Gracias! – markitus82

+0

su bienvenida. ¡buena suerte! – nont

+0

Esto no fue suficiente para nuestra aplicación ... estaba obligado a añadir también la SecurityContext en la sesión de la siguiente manera: session.setAttribute (HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY, SecurityContextHolder.getContext()); –

3

Sí, es posible. Spring Security (como la mayoría del resto de Spring) está basado en interfaz para que pueda conectar sus propias implementaciones de forma selectiva para diferentes partes del marco.

Actualización: Los mecanismos de autorización y autenticación de Spring funcionan en conjunto: el mecanismo de autenticación autenticará al usuario e insertará varias instancias GrantedAuthority en el contexto de seguridad. Estos serán luego verificados por la maquinaria de autorización para permitir/deshabilitar ciertas operaciones.

Utilice la respuesta nont para obtener detalles sobre cómo usar la autenticación preexistente. Los detalles de cómo obtiene los detalles de su sesión (por ejemplo, los roles) dependerán, por supuesto, de su configuración específica. Pero si coloca las instancias GrantedAuthority derivadas de las funciones pre-pobladas en su sesión por su sistema SSO, podrá usarlas en su lógica de autorización.

De la documentación de referencia (con pequeñas modificaciones, con el énfasis es mío):

Usted puede (y muchos usuarios lo hacen) escribir sus propios filtros o controladores MVC para proporcionar interoperabilidad con sistemas de autenticación que no son basado en Spring Security. Por ejemplo, , es posible que esté utilizando Container Managed Autenticación que hace que el usuario actual esté disponible desde una ubicación ThreadLocal o JNDI. O puede trabajar para una compañía que tiene un sistema de autenticación de propiedad heredada, que es un "estándar" corporativo sobre el cual tiene poco control. En tales situaciones es bastante fácil obtener Spring Security para trabajar, y todavía proporcionan capacidades de autorización. Todo lo que necesita hacer es escribir un filtro (o equivalente) que lee la información del usuario de terceros desde una ubicación , construir un muelle seguridad específica Authentication objeto, y lo puso sobre la SecurityContextHolder. Es bastante fácil hacer esto, y es un enfoque de integración totalmente compatible con .

+0

, pero ¿es necesario configurar un AuthenticationProvider? – markitus82

+0

Sí, pero no tiene por qué ser un objeto diferente, entonces el proveedor de autorización: puede crear una clase que implemente ambos (ya que su sistema SSO también parece proporcionarle ambos). –

+0

Lo que sucede es que el formulario de inicio de sesión (autenticación) en mi aplicación se lleva a cabo por sistemas externos. todo lo que tengo es la sesión de usuario y el usuario ya está autenticado. Me gustaría saber cómo puedo obtener el ID de usuario y las funciones de la sesión para usar la Autorización de primavera. – markitus82

2

El servidor que se encarga de la autenticación debe redirigir al usuario a la aplicación pasa a ella algún tipo de clave (un token en CAS SSO). Luego, la aplicación utiliza la clave para preguntar al servidor de autenticación el nombre de usuario y los roles asociados. Con esta información crea un contexto de seguridad que se pasa al administrador de autorizaciones. Esta es una versión muy simplificada de un flujo de trabajo de inicio de sesión de SSO.
Eche un vistazo a CAS SSO y CAS 2 Architecture.
Dime si necesitas más información.

1

hemos tenido el mismo requisito que tuvimos que utilizar la seguridad de la primavera de propósito de autorización solamente. Estábamos usando Siteminder para la autenticación. Puede encontrar más detalles sobre el uso de parte de la autorización de seguridad de resorte no autenticación aquí en http://codersatwork.wordpress.com/2010/02/13/use-spring-security-for-authorization-only-not-for-authentication/

También he añadido el código y casos de prueba de origen en http://code.google.com/p/spring-security-with-authorization-only/source/browse/

1

Estoy tratando de entender la autenticación CAS con nuestra propia autorización y se estaba confundiendo, ya que el objeto Usuario en Spring Security siempre espera que se complete la contraseña y no nos importa eso en nuestro escenario. Después de leer la publicación de Surabh, parece que el truco es devolver un objeto Usuario personalizado sin la contraseña ingresada. Lo probaré y veré si funciona en mi caso. Esperemos que ningún otro código en la cadena espere la Contraseña en el objeto Usuario.

1

utilizo la autorización por esto:

  1. Inyectar el frijol relacionados con la autorización en mi propio café en grano:

    @Autowired 
    private AccessDecisionManager accessDecisionManager; 
    @Autowired 
    FilterSecurityInterceptor  filterSecurityInterceptor; 
    
  2. uso de este cultivo por esto:

    FilterInvocation fi = new FilterInvocation(rundata.getRequest(), rundata.getResponse(), new FilterChain() { 
    
        public void doFilter(ServletRequest arg0, ServletResponse arg1) throws IOException, ServletException { 
         // TODO Auto-generated method stub 
    
        } 
    }); 
    FilterInvocationDefinitionSource objectDefinitionSource = filterSecurityInterceptor.getObjectDefinitionSource(); 
    ConfigAttributeDefinition attr = objectDefinitionSource.getAttributes(fi); 
    Authentication authenticated = new Authentication() { 
    
        ........... 
    
        public GrantedAuthority[] getAuthorities() { 
         GrantedAuthority[] result = new GrantedAuthority[1]; 
         result[0] = new GrantedAuthorityImpl("ROLE_USER"); 
         return result; 
        } 
    }; 
    accessDecisionManager.decide(authenticated, fi, attr); 
    
Cuestiones relacionadas