在网络应用程序中我使用Spring Boot& amp; MVC并且我试图拒绝所有URL的访问,除了/ signin没有登录的用户。为了实现这一点,我设置了HandlerInterceptor的实现,其中preHandler应该将所有无效请求路由到/ signin页面。
设置:
LoginViewController
package com.controller;
import com.model.UserDao;
import com.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.SessionAttributes;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
@Controller
@RequestMapping(value = "/signin")
@SessionAttributes("username")
public class LoginViewController {
@Autowired
private UserService userService;
@RequestMapping(method = RequestMethod.GET)
public ModelAndView showLoginForm(){
return new ModelAndView("login");
}
@RequestMapping(method = RequestMethod.POST)
public ModelAndView verifyLogin(HttpServletRequest request, HttpSession session) {
ModelAndView modelAndView;
String username = request.getParameter("username");
// if login fails, set reload login page
if (userService.verifyUserLogin(username,request.getParameter("password")) == null){
modelAndView = new ModelAndView("login");
modelAndView.addObject("login_failed", true);
} else {
modelAndView = new ModelAndView("index");
session.setAttribute("username", username);
}
return modelAndView;
}
}
AccessInterceptor
package com.spring.interceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import java.util.ArrayList;
public class AccessInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(
HttpServletRequest request,
HttpServletResponse response,
Object handler) throws Exception {
System.out.println(request.getRequestURI());
try {
if (!request.getRequestURI().endsWith("/signin")) {
if (request.getSession()
.getAttribute("username") == null) {
response.sendRedirect(request.getContextPath() + "/signin");
return false;
}
}
} catch (Exception e) {
System.out.println(e.getMessage());
}
return true;
}
@Override
public void postHandle(HttpServletRequest request,
HttpServletResponse response, Object handler,
ModelAndView modelAndView) throws Exception {
System.out.println("Post-handle");
}
@Override
public void afterCompletion(HttpServletRequest request,
HttpServletResponse response, Object handler, Exception ex)
throws Exception {
System.out.println("After completion handle");
}
}
WebApplicationConfig
package com.spring;
import com.spring.interceptor.AccessInterceptor;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.*;
@Configuration
@EnableWebMvc
public class WebApplicationConfig extends WebMvcConfigurerAdapter {
@Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(
new AccessInterceptor()).
addPathPatterns("/**").
excludePathPatterns("/signin/**").
excludePathPatterns("/static/**");
}
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/resources/**").addResourceLocations("/resources/");
}
}
WebApplicationInitializer
package com.spring;
import org.springframework.web.WebApplicationInitializer;
import org.springframework.web.context.ContextLoaderListener;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import org.springframework.web.servlet.DispatcherServlet;
import javax.servlet.ServletContext;
import javax.servlet.ServletRegistration;
public class MyWebAppInitializer implements WebApplicationInitializer {
@Override
public void onStartup(ServletContext container) {
// Create the 'root' Spring application context
AnnotationConfigWebApplicationContext rootContext =
new AnnotationConfigWebApplicationContext();
rootContext.register(WebApplicationConfig.class);
// Manage the lifecycle of the root application context
container.addListener(new ContextLoaderListener(rootContext));
// Create the dispatcher servlet's Spring application context
AnnotationConfigWebApplicationContext dispatcherContext =
new AnnotationConfigWebApplicationContext();
dispatcherContext.register(MyWebAppInitializer.class);
// Register and map the dispatcher servlet
ServletRegistration.Dynamic dispatcher = container.addServlet("dispatcherServlet", new DispatcherServlet(rootContext));
dispatcher.setLoadOnStartup(1);
dispatcher.addMapping("/*");
dispatcher.addMapping("*.css");
dispatcher.addMapping("*.eot");
dispatcher.addMapping("*.svg");
dispatcher.addMapping("*.ttf");
dispatcher.addMapping("*.woff");
dispatcher.addMapping("*.map");
dispatcher.addMapping("*.js");
dispatcher.addMapping("*.ico");
}
}
现在的问题是AccessInterceptor中的System.out.println(request.getRequestURI())
始终打印/error
。因此,即使在调用/signin
时,也始终会重定向请求。另一个有趣的事情是,即使配置了调度程序映射,也不会呈现CSS或其他静态资源。
任何想法?
答案 0 :(得分:0)
答案 1 :(得分:0)
我也在WebLogIntercept(您的MyWebAppInitializer)类中遇到了此问题 我使用以下代码解决了这个问题
添加这两个功能
private Class getClassByName(Class classObject, String name){
Map<Class,List<Field>> fieldMap = new HashMap<>();
Class returnClass = null;
Class tempClass = classObject;
while (tempClass != null) {
fieldMap.put(tempClass,Arrays.asList(tempClass .getDeclaredFields()));
tempClass = tempClass.getSuperclass();
}
for(Map.Entry<Class,List<Field>> entry: fieldMap.entrySet()){
for (Field f : entry.getValue()) {
if(f.getName().equals(name)){
returnClass = entry.getKey();
break;
}
}
}
return returnClass;
}
private Object findCoyoteRequest(Object request) throws Exception {
Class a = getClassByName(request.getClass(),"request");
Field request1 = a.getDeclaredField("request");
request1.setAccessible(true);
Object b = request1.get(request);
if(getClassByName(b.getClass(),"coyoteRequest") == null){
return findCoyoteRequest(b);
}else{
return b;
}
并使用此代码
Object a = findCoyoteRequest(request);
Field coyoteRequest = a.getClass().getDeclaredField("coyoteRequest");
coyoteRequest.setAccessible(true);
Object b = coyoteRequest.get(a);
Field uriMB = b.getClass().getDeclaredField("uriMB");
uriMB.setAccessible(true);
MessageBytes c = (MessageBytes)uriMB.get(b);
System.out.println(c.getString());
c.getString()是realuri
我的英语不好,希望有用
答案 2 :(得分:0)
禁用CFR对我有用 参见https://www.baeldung.com/spring-security-csrf
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable();
}
答案 3 :(得分:-2)
有时,您可以尝试重建项目,这是我的代码:
if(request.getRequestURI().startsWith("/user/")) {return true;}
它总是返回“ /error
”