2011-05-11 59 views
8

我想定制Spring security 3.0.5并将登录URL更改为/ login而不是/ j_spring_security_check。Spring Security定制过滤器

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

的所有首先创建我自己的过滤器使用教程和Spring Security的源代码:

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

<security:http auto-config="true"> 
     <!--<session-management session-fixation-protection="none"/>--> 
     <security:custom-filter ref="myFilter" before="FORM_LOGIN_FILTER"/> 
     <security:intercept-url pattern="/admin/login.jsp*" filters="none"/> 
     <security:intercept-url pattern="/admin/report.html" access="ROLE_ADMIN"/> 
     <security:form-login login-page="/admin/login.jsp" login-processing-url="/login" always-use-default-target="true"/> 
     <security:logout logout-url="/logout" logout-success-url="/login.jsp" invalidate-session="true"/> 
    </security:http> 
<security:authentication-manager alias="authenticationManager"> 
    <security:authentication-provider> 
    <security:password-encoder hash="md5" /> 
    <security:user-service> 
    <!-- peter/opal --> 
     <security:user name="peter" password="22b5c9accc6e1ba628cedc63a72d57f8" authorities="ROLE_ADMIN" /> 
    </security:user-service> 
    </security:authentication-provider> 
</security:authentication-manager> 
<bean id="myFilter" class="com.vanilla.springMVC.controllers.MyFilter"> 
<property name="authenticationManager" ref="authenticationManager"/> 
</bean> 

,然后我有JSP用我的代码。

<form action="../login" method="post"> 
    <label for="j_username">Username</label> 
    <input type="text" name="j_username" id="j_username" /> 
    <br/> 
    <label for="j_password">Password</label> 
    <input type="password" name="j_password" id="j_password"/> 
    <br/> 
    <input type='checkbox' name='_spring_security_remember_me'/> Remember me on this computer. 
    <br/> 
    <input type="submit" value="Login"/> 
</form> 

当试图导航到/admin/report.html我被重定向到登录页面。 但提交凭据后,我越来越:

HTTP Status 404 - /SpringMVC/login/ 

type Status report 

message /SpringMVC/login/ 

description The requested resource (/SpringMVC/login/) is not available. 

它看起来像我在配置问题,但我无法弄清楚什么导致此。 你能帮忙吗?

+0

**'action =“../ login”'**? – lschin 2011-05-12 02:23:27

+0

这是正确的,../login,因为othrwise我会得到/ admin /登录,我需要父文件夹。 – 2011-05-12 06:47:48

+0

你的应用程序的根目录是'/ SpringMVC'? '/ SpringMVC/login /'是否正确/应该可用? – lschin 2011-05-12 08:42:09

回答

0

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

我唯一能想到的其他事情就是检查web.xml中的过滤器映射。既然你正在登录页面,你有这个设置,但我会检查你是不是只拦截具有特定扩展名的网址等。

此外,就像一个fyi,如果你想要求(一旦登录表单认证用户)转到受保护的资源(在这种情况下为/admin/report.html),那么您应该删除表单:login always-use-default-target =“true”。将此标志设置为true将导致请求始终转到默认的目标url,这通常不是您想要的。从spring security docs

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

+0

有关downvote的更多信息,请参阅下面的答案 – 2015-08-19 21:53:04

10

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

<form-login login-page="/login" login-processing-url="/login.do" default-target-url="/" always-use-default-target="true" authentication-failure-url="/login?error=1" username-parameter="username" password-parameter="password"/> 
相关问题