2011-04-17 21 views

Respuesta

14

Primavera-seguridad tiene una configuración tal. see here para saber cómo hacerlo. En pocas palabras - se fuerza el canal a utilizar https:

<http> 
    <intercept-url pattern="/secure/**" access="ROLE_USER" 
     requires-channel="https"/> 
    <intercept-url pattern="/**" access="ROLE_USER" 
     requires-channel="any"/> 
</http> 

Si no desea utilizar resortes de seguridad, aquí está un interceptor que escribí:

@Component 
public class SslInterceptor extends HandlerInterceptorAdapter { 

    // no need to inject it for now.. 
    private PathMatcher pathMatcher = new AntPathMatcher(); 

    @Value("${base.url.secure}") 
    private String secureRoot; 

    @Resource(name="secureLocations") 
    private List<String> secureLocations; 

    @Value("${use.ssl}") 
    private boolean useSsl; 


    @Override 
    public boolean preHandle(HttpServletRequest request, 
      HttpServletResponse response, Object handler) throws Exception { 

     if (useSsl && !request.isSecure() && shouldForceSecure(request.getRequestURI())) { 

      String redirectUrl = secureRoot + request.getRequestURI(); 
      if (request.getQueryString() != null) { 
       redirectUrl += "?" + request.getQueryString(); 
      } 
      // force session creation - thus it will be accessible to both the 
      // secure and the insecure contexts 
      request.getSession(true); 
      response.sendRedirect(redirectUrl); 
      return false; 
     } 

     return true; 
    } 

    private boolean shouldForceSecure(String path) { 
     for (String pattern : secureLocations) { 
      if (pathMatcher.match(pattern, path)) { 
       return true; 
      } 
     } 
     return false; 
    } 
} 
+0

Gracias Bozho. El ejemplo se ve genial. También puede compartir conmigo cómo se puede hacer usando la configuración de seguridad de primavera. –

+0

ver actualizado .... – Bozho

+0

Exactamente lo que quiero. De hecho, vi este artículo antes de publicar la pregunta. Soy nuevo en Spring MVC. Puse el archivo de configuración de Spring pero estaba obteniendo errores de análisis. Sé que estoy pidiendo demasiado, pero ¿pueden darme un archivo XML de muestra? Gracias Bozho. –

1

Puede hacerlo en su configuración de Tomcat.

intente agregar redirectPort = "" en server.xml al conector HTTP.

Espero que ayude.

Actualización:

este artículo se explicará cómo tratar con SSL y tiene una gran cantidad de un ejemplos.

http://tomcat.apache.org/tomcat-6.0-doc/ssl-howto.html

+0

Bueno, sólo ayuda si están utilizando Tomcat ... – skaffman

+0

de acuerdo, pero cada servidor de aplicaciones tiene tales opciones incluso IIS :). Simplemente escribí la idea de lo que debería hacerse. –

+0

Por favor, puede dar un ejemplo –

2

Para un enfoque basado en la anotación sin Spring Security I escribió un interceptor y una nueva anotación: método de controlador de

/** 
* Request mapping annotation to enforce secure or insecure requests. 
* Per default the annotated mapping is enforced to be secure. 
* 
* @see org.springframework.web.bind.annotation.RequestMapping 
*/ 
@Target({ElementType.METHOD, ElementType.TYPE}) 
@Retention(RetentionPolicy.RUNTIME) 
@Documented 
@Mapping 
public @interface RequestProtocol { 

    boolean secure() default true; 
} 

Así que usted puede simplemente declarar una (aquí por REST) ​​así:

@RequestMapping(value = "/secret", method = RequestMethod.GET) 
@RequestProtocol(secure = true) 
@ResponseBody 
public Result doSecure(@Valid Model model) { 
    return doSomething(model)); 
} 

Para habilitar la asignación, utilice un interceptor que redirija el protocolo incorrecto. También puede hacer un manejo más simple simplemente enviando una respuesta PROHIBIDA.

/** 
* Interceptor to send a redirect on security enforced mappings with wrong type of request. 
* 
* @see RequestProtocol 
*/ 
class RequestProtocolInterceptor extends HandlerInterceptorAdapter { 

    private static final int PORT_DIFF = 443 - 80; 

    @Override 
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws IOException { 
    Boolean secure = checkSecure(handler); 
    if (secure != null && request.isSecure() != secure) { 
     response.sendRedirect(switchSecure(secure, request.getRequestURL())); 
     return false; 
    } 
    return true; 
    } 

    private Boolean checkSecure(Object handler) { 
    if (handler instanceof HandlerMethod) { 
     HandlerMethod method = (HandlerMethod)handler; 
     RequestProtocol annotation = method.getMethodAnnotation(RequestProtocol.class); 
     if (annotation == null) { 
     annotation = AnnotationUtils.findAnnotation(method.getBeanType(), RequestProtocol.class); 
     } 
     return annotation == null ? null : annotation.secure(); 
    } 
    return null; 
    } 

    private String switchSecure(boolean secure, StringBuffer url) { 
    int endSchema = url.indexOf("://"); 
    url.replace(0, endSchema, secure ? "https" : "http"); 
    int startPort = url.indexOf(":", endSchema + 3); 
    if (startPort != -1) { 
     int endPort = url.indexOf("/", startPort); 
     int port = Integer.parseInt(url.substring(startPort + 1, endPort)); 
     port += secure ? PORT_DIFF : -PORT_DIFF; 
     url.replace(startPort + 1, endPort, String.valueOf(port)); 
    } 
    return url.toString(); 
    } 
} 

Para habilitar el interceptor basado en una anotación de configuración pura de manantial, utilice el WebMvcConfigurerAdapter:

@Configuration 
@EnableWebMvc 
public class MyConfiguration extends WebMvcConfigurerAdapter { 

    @Override 
    public void addInterceptors(InterceptorRegistry registry) { 
    registry.addInterceptor(new RequestProtocolInterceptor()); 
    } 
} 
Cuestiones relacionadas