authentication - maximum - Seguridad de muelle: autorización sin autenticación.
spring security session timeout (7)
Estoy tratando de integrar Spring Security en mi aplicación web. Parece bastante fácil de hacer siempre y cuando integres todo el proceso de autenticación y autorización.
Sin embargo, tanto la autenticación como la autorización parecen estar tan acopladas que me lleva mucho tiempo comprender cómo podría dividir estos procesos y obtener la 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?
El servidor que maneja la autenticación debe redirigir al usuario a la aplicación que le pasa algún tipo de clave (un token en CAS SSO). Luego, la aplicación usa la clave para solicitar al servidor de autenticación el nombre de usuario y los roles asociados. Con esta información, cree 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 SSO.
Echa un vistazo a CAS SSO y CAS 2 Architecture .
Dime si necesitas más información.
Estoy tratando de entender la autenticación CAS con nuestra propia Autorización y me estaba confundiendo ya que el objeto Usuario en Spring Security siempre espera que se ingrese 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 de Usuario personalizado sin la contraseña completada. Lo intentaré y veré si funciona en mi caso. Con suerte, ningún otro código de la cadena esperará la contraseña en el objeto Usuario.
Si es posible. Spring Security (como la mayoría del resto de Spring) está guiado por una 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 juntos: el mecanismo de autenticación autentificará al usuario e insertará varias instancias de GrantedAuthority
en el contexto de seguridad. Estos serán revisados por la maquinaria de autorización para permitir / rechazar ciertas operaciones.
Use la respuesta de no 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 de GrantedAuthority
derivadas de los roles GrantedAuthority
previamente en su sesión por su sistema de SSO, podrá usarlos en su lógica de autorización.
De la documentación de referencia (ligeramente editada, con mi énfasis):
Puede (y muchos usuarios lo hacen) escribir sus propios filtros o controladores MVC para proporcionar interoperabilidad con sistemas de autenticación que no se basan en Spring Security. Por ejemplo, podría estar usando la autenticación administrada por contenedor que hace que el usuario actual esté disponible desde una ubicación
ThreadLocal
oJNDI
. O puede trabajar para una compañía que tiene un sistema de autenticación patentado heredado, que es un "estándar" corporativo sobre el que tiene poco control. En tales situaciones, es bastante fácil hacer que Spring Security funcione y aún así proporcionar capacidades de autorización. Todo lo que debe hacer es escribir un filtro (o equivalente) que lea la información del usuario de terceros desde una ubicación, genere un objeto deAuthentication
específico de Spring Security y colóquelo enSecurityContextHolder
. Es bastante fácil hacer esto, y es un enfoque de integración totalmente compatible.
Si su autenticación ya se realizó con un servicio de SSO, entonces debe usar uno de los filtros de autenticación previa de Spring Security. Luego, puede especificar un servicio UserDetails (posiblemente personalizado) que usará el principio de usuario pre-autenticado para completar el GrantedAuthority''s
SpringSecurity incluye varios filtros de autenticación previa, incluidos J2eePreAuthenticatedProcessingFilter y RequestHeaderPreAuthenticatedProcessingFilter. Si no puede encontrar uno que funcione para usted, también es posible, y no es tan difícil escribir el suyo, siempre y cuando sepa en qué parte de la solicitud su implementación de SSO rellena los datos. (Eso depende de la implementación del curso.)
Simplemente implemente la interfaz de Filter y haga 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);
}
Yo también pasé muchas horas investigando cómo implementar la autorización personalizada sin autenticación.
El proceso de autenticación es externo a nuestro sistema (basado en el inicio de sesión único). Lo he hecho, como se menciona a continuación y funciona !!! (Estoy seguro de que hay muchas otras formas de hacerlo mejor, pero de esta manera solo se adapta a mi situación)
Escenario: el usuario ya está autenticado por un sistema externo y toda la información necesaria para la autorización está presente en la solicitud
1. Es necesario crear la configuración de seguridad, habilitando la seguridad del método global como se muestra a continuación.
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(securedEnabled = true, prePostEnabled = true)
class SpringWebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(final HttpSecurity http) throws Exception {
}
}
2.) Implementar Spring PermissionEvaluator para autorizar si la solicitud debe permitirse o rechazarse
@Component
public class CustomPermissionEvaluator implements PermissionEvaluator {
public boolean authorize(final String groups, final String role) {
boolean allowed = false;
System.out.println("Authorizing: " + groups + "...");
if (groups.contains(role)) {
allowed = true;
System.out.println(" authorized!");
}
return allowed;
};
@Override
public boolean hasPermission(final Authentication authentication, final Object groups, final Object role) {
return authorize((String) groups, (String) role);
};
@Override
public boolean hasPermission(final Authentication authentication, final Serializable targetId, final String targetType, final Object permission) {
return authorize((String) targetId, (String) permission);
};
}
3.) Añadir MethodSecurityConfig
@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class MethodSecurityConfig extends GlobalMethodSecurityConfiguration {
@Override
protected MethodSecurityExpressionHandler createExpressionHandler() {
DefaultMethodSecurityExpressionHandler expressionHandler = new DefaultMethodSecurityExpressionHandler();
expressionHandler.setPermissionEvaluator(new CustomPermissionEvaluator());
return expressionHandler;
}
}
4.) Agregue @PreAuthorize en su controlador como se muestra a continuación. En este ejemplo, todos los grupos del usuario están presentes en el encabezado de solicitud con la clave ''availableUserGroups''. Esto luego se pasa al CustomPermissionEvaluator para verificar la autorización. Tenga en cuenta que Spring pasa automáticamente el objeto de autenticación al método ''hasPermission''. Por lo tanto, en caso de que desee cargar un usuario y verificarlo con el método ''hasRole'' de spring, puede usarlo.
@PreAuthorize("hasPermission(#userGroups, ''ADMIN'')")
@RequestMapping(value = "/getSomething")
public String getSomething(@RequestHeader(name = "availableUserGroups") final String userGroups) {
return "resource allowed to access";
}
Manejo de otros escenarios: 1.) En el escenario en el que desea cargar el usuario antes de poder realizar la autorización. Puede usar pre-authentication filtros de pre-authentication Spring y hacerlo de una manera similar. Ejemplo de enlace: http://www.learningthegoodstuff.com/2014/12/spring-security-pre-authentication-and.html
Yo uso la autorización por esto:
Inyectar el bean relacionado con la autorización en mi propio bean:
@Autowired private AccessDecisionManager accessDecisionManager; @Autowired FilterSecurityInterceptor filterSecurityInterceptor;
Utilice este frijol por este:
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);
hemos tenido el mismo requisito cuando tuvimos que usar la seguridad de Spring solo para fines de autorización. Estábamos usando Siteminder para la autenticación. Puede encontrar más detalles sobre cómo usar la parte de autorización de la seguridad de Spring, no la autenticación aquí en http://codersatwork.wordpress.com/2010/02/13/use-spring-security-for-authorization-only-not-for-authentication/
También he agregado código fuente y casos de prueba en http://code.google.com/p/spring-security-with-authorization-only/source/browse/