Spring3 MVC Login Interceptor

折月煮酒 提交于 2019-12-03 20:36:01

在学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






易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!