Spring 重定向到资源的安全自定义登录表单不可用

Spring security custom login form redirecting to resource not available

我是 Spring 安全 4 的新手。我用 struts 2 和 spring 安全制作了一个简单的应用程序。我正在使用自定义登录表单。发生的事情是当我提交登录表单时我被重定向到 http://localhost:8080/SpringSecurity/admin 但我仍然收到以下错误

HTTP 状态 404 - /SpringSecurity/admin

类型状态报告

留言/SpringSecurity/admin

说明请求的资源不可用。

login.jsp

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
    <form action="admin" method="post">
        <label>Username</label><input type="text" id="username" name="username" /> <label>Password</label><input
            type="text" id="password" name="password" /> <input name="submit" type="submit" />
    </form>
</body>
</html>

admin.jsp

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
HELLO
</body>
</html>

spring-security.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/security"
    xmlns:beans="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-4.1.xsd
    http://www.springframework.org/schema/security
    http://www.springframework.org/schema/security/spring-security-4.1.xsd">
    <http use-expressions="true">
    <csrf disabled="true"/>
        <intercept-url pattern="/login" access="permitAll"/>
        <intercept-url pattern="/admin" access="hasRole('ROLE_USER')" /> 
        <form-login login-page="/login" authentication-failure-url="/error" login-processing-url="/admin" authentication-success-forward-url="/admin" />
    </http>
    <authentication-manager>
        <authentication-provider>   
            <user-service>
                <user name="mayank" password="mayank" authorities="ROLE_USER"   />
            </user-service>
        </authentication-provider>
    </authentication-manager>
</beans:beans>

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
  <display-name>SpringSecurity</display-name>
  <welcome-file-list>
    <welcome-file>index.html</welcome-file>
    <welcome-file>index.htm</welcome-file>
    <welcome-file>login.jsp</welcome-file>
    <welcome-file>default.html</welcome-file>
    <welcome-file>default.htm</welcome-file>
    <welcome-file>default.jsp</welcome-file>
  </welcome-file-list>
  <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>/WEB-INF/spring-security.xml</param-value>
  </context-param>
  <filter>
    <filter-name>springSecurityFilterChain</filter-name>
    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
  </filter>
  <filter-mapping>
    <filter-name>springSecurityFilterChain</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>
  <filter>
  <filter-name>struts2</filter-name>
  <filter-class>org.apache.struts2.dispatcher.filter.StrutsPrepareAndExecuteFilter</filter-class>
  </filter>
  <filter-mapping>
  <filter-name>struts2</filter-name>
  <url-pattern>/*</url-pattern>
  </filter-mapping>
  <listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  </listener>
</web-app>

struts.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
"http://struts.apache.org/dtds/struts-2.3.dtd">
<struts>
    <package name="default" namespace="/" extends="struts-default">
        <action name="admin" class="controller.AdminController"
            method="execute">
            <result name="success">/WEB-INF/admin.jsp</result>
        </action>
        <action name="login">
            <result>/WEB-INF/login.jsp</result>
        </action>
        <action name="error">
        <result>/WEB-INF/error.jsp</result>
        </action>
    </package>
</struts>

管理员控制器

public class AdminController extends HttpServlet {

    private String username;
    private String password;

    public String execute(){
        System.out.println(getUsername()+" "+getPassword());
        return "success";
    }
    public String getUsername() {
        return username;
    }
    public void setUsername(String username) {
        this.username = username;
    }
    public String getPassword() {
        return password;
    }
    public void setPassword(String password) {
        this.password = password;
    }
}

下面是堆栈跟踪。我明白了

- /admin at position 1 of 10 in additional filter chain; firing Filter: 'SecurityContextPersistenceFilter'
- Obtained a valid SecurityContext from SPRING_SECURITY_CONTEXT: 'org.springframework.security.core.context.SecurityContextImpl@fb929c69: Authentication: org.springframework.security.authentication.UsernamePasswordAuthenticationToken@fb929c69: Principal: org.springframework.security.core.userdetails.User@bf8f9e59: Username: mayank; Password: [PROTECTED]; Enabled: true; AccountNonExpired: true; credentialsNonExpired: true; AccountNonLocked: true; Granted Authorities: ROLE_USER; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@0: RemoteIpAddress: 0:0:0:0:0:0:0:1; SessionId: 89A6B91ADDB34C56892BA52AABFFFB38; Granted Authorities: ROLE_USER'
- /admin at position 2 of 10 in additional filter chain; firing Filter: 'WebAsyncManagerIntegrationFilter'
- /admin at position 3 of 10 in additional filter chain; firing Filter: 'HeaderWriterFilter'
- /admin at position 4 of 10 in additional filter chain; firing Filter: 'UsernamePasswordAuthenticationFilter'
- Checking match of request : '/admin'; against '/admin'
- Request is to process authentication
- Authentication attempt using org.springframework.security.authentication.dao.DaoAuthenticationProvider
- Delegating to org.springframework.security.web.authentication.session.ChangeSessionIdAuthenticationStrategy@51602eeb
- Authentication success. Updating SecurityContextHolder to contain: org.springframework.security.authentication.UsernamePasswordAuthenticationToken@fb929c69: Principal: org.springframework.security.core.userdetails.User@bf8f9e59: Username: mayank; Password: [PROTECTED]; Enabled: true; AccountNonExpired: true; credentialsNonExpired: true; AccountNonLocked: true; Granted Authorities: ROLE_USER; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@0: RemoteIpAddress: 0:0:0:0:0:0:0:1; SessionId: CCF2FB776A4077BCCD71705E9A2CEAEF; Granted Authorities: ROLE_USER
- Not injecting HSTS header since it did not match the requestMatcher org.springframework.security.web.header.writers.HstsHeaderWriter$SecureRequestMatcher@60539cb2
- SecurityContext 'org.springframework.security.core.context.SecurityContextImpl@fb929c69: Authentication: org.springframework.security.authentication.UsernamePasswordAuthenticationToken@fb929c69: Principal: org.springframework.security.core.userdetails.User@bf8f9e59: Username: mayank; Password: [PROTECTED]; Enabled: true; AccountNonExpired: true; credentialsNonExpired: true; AccountNonLocked: true; Granted Authorities: ROLE_USER; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@0: RemoteIpAddress: 0:0:0:0:0:0:0:1; SessionId: CCF2FB776A4077BCCD71705E9A2CEAEF; Granted Authorities: ROLE_USER' stored to HttpSession: 'org.apache.catalina.session.StandardSessionFacade@3c23a642
- SecurityContextHolder now cleared, as request processing completed

我想通了。 Spring 安全过滤器之一正在尝试转发管理操作,但我没有使用 FORWARD 调度程序配置 StrutsPrepareAndExecuteFilter。因此,它说资源不可用。 正确的配置将是

 <filter>
  <filter-name>struts2</filter-name>
  <filter-class>org.apache.struts2.dispatcher.filter.StrutsPrepareAndExecuteFilter</filter-class>
  </filter>
  <filter-mapping>
  <filter-name>struts2</filter-name>
  <url-pattern>/*</url-pattern>
  <dispatcher>FORWARD</dispatcher>
  <dispatcher>REQUEST</dispatcher>
  </filter-mapping>