Spring Security自定义filter

我想自定义Spring security 3.0.5并将登录URL更改为/ login而不是/ j_spring_security_check。

我需要做的是允许登录“/”目录并保护“/admin/report.html”页面。

首先,我使用教程和Spring Security源代码创建自己的filter:

public class MyFilter extends AbstractAuthenticationProcessingFilter { private static final String DEFAULT_FILTER_PROCESSES_URL = "/login"; private static final String POST = "POST"; public static final String SPRING_SECURITY_FORM_USERNAME_KEY = "j_username"; public static final String SPRING_SECURITY_FORM_PASSWORD_KEY = "j_password"; public static final String SPRING_SECURITY_LAST_USERNAME_KEY = "SPRING_SECURITY_LAST_USERNAME"; private String usernameParameter = SPRING_SECURITY_FORM_USERNAME_KEY; private String passwordParameter = SPRING_SECURITY_FORM_PASSWORD_KEY; protected MyFilter() { super(DEFAULT_FILTER_PROCESSES_URL); } @Override public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException, IOException, ServletException { String username = obtainUsername(request); String password = obtainPassword(request); if (username == null) { username = ""; } if (password == null) { password = ""; } username = username.trim(); UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(username, password); HttpSession session = request.getSession(false); if (session != null || getAllowSessionCreation()) { request.getSession().setAttribute(SPRING_SECURITY_LAST_USERNAME_KEY, TextEscapeUtils.escapeEntities(username)); } setDetails(request, authRequest); return this.getAuthenticationManager().authenticate(authRequest); } protected void setDetails(HttpServletRequest request, UsernamePasswordAuthenticationToken authRequest) { authRequest.setDetails(authenticationDetailsSource.buildDetails(request)); } @Override public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException { final HttpServletRequest request = (HttpServletRequest) req; final HttpServletResponse response = (HttpServletResponse) res; if (request.getMethod().equals(POST)) { // If the incoming request is a POST, then we send it up // to the AbstractAuthenticationProcessingFilter. super.doFilter(request, response, chain); } else { // If it's a GET, we ignore this request and send it // to the next filter in the chain. In this case, that // pretty much means the request will hit the /login // controller which will process the request to show the // login page. chain.doFilter(request, response); } } protected String obtainUsername(HttpServletRequest request) { return request.getParameter(usernameParameter); } protected String obtainPassword(HttpServletRequest request) { return request.getParameter(passwordParameter); } } 

之后我在xml中进行了以下更改

   <!---->                   

然后我用我的代码编写JSP。

 


Remember me on this computer.

当我尝试导航到/admin/report.html时,我被重定向到登录页面。 但在提交凭据后我得到了:

 HTTP Status 404 - /SpringMVC/login/ type Status report message /SpringMVC/login/ description The requested resource (/SpringMVC/login/) is not available. 

看起来我的配置有问题,但我无法弄清楚导致这种情况的原因。 你能帮我吗?

我认为@Ischin对forms动作url的疑问是正确的。 尝试放入完整路径,看看是否有效。 如果是这样,你可以从那里找出不匹配的东西。

我能想到要检查的另一件事是web.xml中的filter映射。 由于您正在登录页面,因此您已设置此设置,但我会检查您是否不仅截取具有特定扩展名的url等。

此外,就像fyi一样,如果您希望请求(一旦登录表单对用户进行身份validation)转到安全资源(在这种情况下为/admin/report.html),那么您应该删除表单:login always-use-默认目标=“真”。 将此标志设置为true将导致请求始终转到默认目标URL,这通常不是您想要的。 从春季安全文档 :

映射到UsernamePasswordAuthenticationFilter的defaultTargetUrl属性。 如果未设置,则默认值为“/”(应用程序根目录)。 登录后,用户将被带到此URL,前提是他们在尝试访问安全资源时未被要求登录,而这些用户将被带到最初请求的URL。

我迟到了大约12个月,但是为了自定义Spring Security表单登录的登录URL,您不需要创建自己的filter。 form-login标签的一个属性允许您设置自定义URL。 实际上,您还可以使用form-login标记的属性更改默认的j_username和j_password字段名称。 这是一个例子: