`

转:Spring3 MVC Login Interceptor

 
阅读更多

在学spring3 mvc,做了个简单的CRUD,但是用户不登录也能直接访问任何页面。我的想法是写个SecurityInterceptor在preHandle中判断session是不是存在user对象。配置如下:

 

<mvc:interceptors>
  <mvc:interceptor>
    <mvc:mapping path="/*" />
    <bean class="smartcrud.common.spring.SecurityInterceptor">
    </bean>
  </mvc:interceptor>
</mvc:interceptors>

 

 

 代码如下:

 

public class SecurityInterceptor implements HandlerInterceptor {
 
  @Override
  public boolean preHandle(HttpServletRequest request,
      HttpServletResponse response, Object handler) throws Exception {
    // intercept
    HttpSession session = request.getSession();
    if (session.getAttribute("user") == null) {
      throw new AuthorizationException();
    } else {
      return true;
    }
  }

 很快,我发现登录页面是不需要拦截的。。搜索了一下。<mvc:interceptor>没有提供配置exclude url的功能。只能在SecurityInterceptor中手动处理。。于是修改配置如下:

<mvc:interceptors>
  <mvc:interceptor>
    <mvc:mapping path="/*" />
    <bean class="smartcrud.common.spring.SecurityInterceptor">
      <property name="excludedUrls">
        <list>
          <value>/login</value>
        </list>
      </property>
    </bean>
  </mvc:interceptor>
</mvc:interceptors>

 修改代码如下:

 

 

public class SecurityInterceptor implements HandlerInterceptor {
  private List<String> excludedUrls;
 
  public void setExcludedUrls(List<String> excludedUrls) {
    this.excludedUrls = excludedUrls;
  }
 
  @Override
  public boolean preHandle(HttpServletRequest request,
      HttpServletResponse response, Object handler) throws Exception {
    // excluded URLs:
    // see http://stackoverflow.com/questions/9908124/spring-mvc-3-interceptor-on-all-excluding-some-defined-paths
    String requestUri = request.getRequestURI();
    for (String url : excludedUrls) {
      if (requestUri.endsWith(url)) {
        return true;
      }
    }
 
    // intercept
    HttpSession session = request.getSession();
    if (session.getAttribute("user") == null) {
      // see http://stackoverflow.com/questions/12713873/spring-3-1-how-do-you-send-all-exception-to-one-page
      throw new AuthorizationException();
    } else {
      return true;
    }
  }

 这样以/login结尾的请求不做拦截处理。。

 

接下来需要处理非/login结尾的情况,此时我设计为抛出一个自定义的AuthorizationException异常。 

 

 

public class AuthorizationException extends Exception {
}

 当抛出这个异常时,spring框架应该能够处理它,并将用户导向/WEB-INF/views/adminLogin.jsp页面以便让用户登录。。

 

 

搜索了一下资料,配置如下:

<bean id="handlerExceptionResolver"
  class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
  <property name="exceptionMappings">
    <props>
      <prop key="smartcrud.common.exception.AuthorizationException">redirect:/login</prop>
    </props>
  </property>
</bean>

 注意这里的视图名为redirect:/login,spring会去找标记了@RequestMapping(value="/login")的方法来处理它。

代码如下:

@Controller
public class LoginController {
  @Autowired
  private UserService userService;
 
  @RequestMapping(value = "/login", method = RequestMethod.GET)
  public String loginForm() {
    return "adminLogin";
  }

 如果handlerExceptionResolver那里的视图名没有redirect前缀,像这样

  class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
  <property name="exceptionMappings">
    <props>
      <prop key="smartcrud.common.exception.AuthorizationException">/login</prop>
    </props>
  </property>
</bean>

 

 spring会尝试去找/WEB-INF/views/login.jsp。。如果恰好登录页面不叫这个名字,spring就会给出404,搞不懂spring为什么不去@RequestMapping中查找呢。

参考:

http://stackoverflow.com/questions/9908124/spring-mvc-3-interceptor-on-all-excluding-some-defined-paths
http://stackoverflow.com/questions/12713873/spring-3-1-how-do-you-send-all-exception-to-one-page 

 

 

转载自:http://www.itniwo.net/blog/v/254207.html

 

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics