2011-04-17 121 views

回答

14

春季安全具有這樣的配置。 see here如何做到這一點。總之 - 你強制通道使用https:

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

如果你不想使用Spring的安全,下面是我寫的攔截:

@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

感謝Bozho。這個例子看起來不錯。你能否也請與我分享如何使用彈簧安全配置來完成這項工作。 – 2011-04-17 09:19:16

+0

看到更新.... – Bozho 2011-04-17 09:23:46

+0

正是我想要的。事實上,我在發佈問題之前看過這篇文章。我是Spring MVC的新手。我把彈簧配置文件,但我得到解析錯誤。我知道我問得太多,但你能給我一個示例XML文件嗎?謝謝Bozho。 – 2011-04-17 09:31:56

1

您可以在Tomcat配置中執行此操作。

嘗試將server.xml中的redirectPort =「」添加到HTTP連接器。

希望它有幫助。

更新:

本文將解釋你如何處理SSL,有很多的例子。

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

+0

那麼它只有幫助,如果他們使用Tomcat ... – skaffman 2011-04-17 08:52:47

+0

同意,但每個應用服務器這樣的選項甚至IIS :)。我只是寫了這個想法應該做什麼。 – 2011-04-17 08:54:32

+0

請你可以提供一個例子 – 2011-04-17 08:54:42

2

對於註釋爲基礎的方法,而不春天的安全我寫了一個攔截器和一個新的註解:像這樣

/** 
* 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; 
} 

所以,你可以簡單地聲明(這裏REST)控制器的方法:

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

要啓用映射,請使用攔截器重定向錯誤的協議。您也可以通過發送FORBIDDEN響應來進行更簡單的處理。

/** 
* 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(); 
    } 
} 

要啓用一個純粹的基於註釋的Spring配置的攔截器,使用WebMvcConfigurerAdapter:

@Configuration 
@EnableWebMvc 
public class MyConfiguration extends WebMvcConfigurerAdapter { 

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