2011-05-11 133 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"/> 
相關問題