2013-08-02 105 views
0

我試圖在cq5中實現註銷servlet,我需要從cas服務器和cq5註銷我的用戶。 問題是我需要servlet既從cq5註銷,然後重定向到cas註銷頁面,但由於我使用響應來執行這兩件事情,所以我得到一個IllegalStateException異常。LogoutServlet上的IllegalStateException

任何想法如何做到這一點?

這是我的servlet代碼:

import com.stuff.etc.*; 

@Component(metatype = false) 
@SlingServlet(
     methods = {"GET"}, 
     generateComponent = false   
) 
@Service 
public class MyLogoutServlet extends SlingAllMethodsServlet { 

    @Reference(cardinality = ReferenceCardinality.OPTIONAL_UNARY, policy = ReferencePolicy.DYNAMIC) 
    private Authenticator authenticator; 

    public static final String PAR_USER = "username"; 

    @Property(name = "sling.servlet.paths") 
    public static final String SERVLET_PATH = "/system/mysite/logout"; 

    @Property(name = "sling.auth.requirements", propertyPrivate = true) 
    //@SuppressWarnings("unused") 
    private static final String[] AUTH_REQUIREMENT = { "-" + SERVLET_PATH }; 

    private static final Logger log = LoggerFactory.getLogger(CookieStoreUtil.class); 

    public static final String TOKEN_COOKIE_ID = "mysite_auth"; 

    private static final String LOGOUT_RESOURCE = "https://casurl.com/logout"; 

    @Reference 
    private CryptoSupport cryptoSupport; 

    @Reference 
    private SlingSettingsService settingsService; 

    @Override 
    protected void doGet(SlingHttpServletRequest request, SlingHttpServletResponse response) throws ServletException, IOException { 
     String username = request.getParameter(PAR_USER);      

     final Authenticator authenticator = this.authenticator; 
     log.info(String.valueOf(authenticator==null)); 

     if(username != null) { 
      if(log.isDebugEnabled()) { 
       log.debug("Request to logout user: " + username); 
      } 
      request.removeAttribute(WSCAuthToken.TOKEN_ATTR_USER); 
      WSCAuthToken token = getAuthToken(request, cryptoSupport); 

      //if(token != null && token.isDebugMode()) { 
      if(token != null) { 
       token.setUser(null); 
       token.resetAttributes(); 
       saveAuthCookie(request, response, cryptoSupport, token); 

       CookieStoreUtil.resetStoreCookie(request, response, settingsService);    
       TokenCookie.setCookie(response, TOKEN_COOKIE_ID, "", -1, "/", null, false, request.isSecure()); 

       if (authenticator != null) { 
        try { 
         log.info("SIAMO QUI"); 
         log.info("ANDIAMO QUI: "+request.getContextPath()); 
         AbstractAuthenticationHandler.setLoginResourceAttribute(request, request.getContextPath()); 
         authenticator.logout(request, response); 
        } catch (IllegalStateException ise) { 
         log.error("service: Response already committed, cannot logout"); 
         return; 
        } 
       } else { 
        log.error("service: Authenticator service missing, cannot logout"); 
       } 

      } else { 
       response.sendError(HttpServletResponse.SC_UNAUTHORIZED);   
      }       
     } else { 
      response.sendError(HttpServletResponse.SC_BAD_REQUEST, "Username non specificato");  
     } 
     response.sendRedirect(LOGOUT_RESOURCE); 
     //response.setStatus(HttpServletResponse.SC_NO_CONTENT); 
    } 

    public static WSCAuthToken getAuthToken(HttpServletRequest request, CryptoSupport cryptoSupport) { 
     WSCAuthToken token = null; 

     Object tokenAttr = request.getAttribute(TOKEN_COOKIE_ID); 
     if ((tokenAttr instanceof WSCAuthToken)) {   
      return (WSCAuthToken)tokenAttr; 
     } 

     String cookie = TokenCookie.getCookie(request, TOKEN_COOKIE_ID);        

     if (cookie != null) { 
      String value; 
      try { 
       value = cryptoSupport.unprotect(cookie); 
       token = WSCAuthToken.fromJSON(value); 
      } catch (CryptoException e) { 
       log.error("CryptoException getting token: " + e.getMessage()); 
      }   
     } 
     return token; 
    } 

    public static void saveAuthCookie(HttpServletRequest request, HttpServletResponse response, 
      CryptoSupport cryptoSupport, WSCAuthToken token) { 

     try {   
      request.setAttribute(token.getCk(), token); 
      String value = cryptoSupport.protect(token.toJSON());   
      TokenCookie.setCookie(response, TOKEN_COOKIE_ID, "\"" + value + "\"", -1, "/", null, true, request.isSecure());   
     } catch (CryptoException e) { 
      log.error("CryptoException saving cookie", e); 
     } catch (IOException e) { 
      log.error("IOException saving cookie", e); 
     } 
    } 
} 

的日誌錯誤: 02.08.2013 11:03:23.966 *ERROR* [127.0.0.1 [1375434203945] GET /system/sorgeniabpp/logout HTTP/1.1] org.apache.sling.engine.impl.SlingRequestProcessorImpl service: Uncaught Throwable java.lang.IllegalStateException: response already committed

而且另一個問題是,我甚至不得到CQ5註銷。我試圖合併我的servlet與org.apache.sling.auth.core.impl.LogoutServlet上實現的代碼,但沒有結果。

回答

0

你需要添加迴歸後也sendError(如已@suresh阿塔告訴你,你需要經過重定向添加語句)聲明。
Accroding到HttpServletResponse#sendRedirectHttpServletResponse#sendError

If the response has already been committed, this method throws an IllegalStateException.After using this method, the response should be considered to be committed and should not be written to.

所以經過sendError也return語句。

response.sendError(HttpServletResponse.SC_UNAUTHORIZED); 
return; 

response.sendError(HttpServletResponse.SC_BAD_REQUEST, "Username non specificato"); 
return; 

與此

response.sendRedirect(LOGOUT_RESOURCE); 
return; 

爲更多細節why you need to add return statement after redirect or sendError

0

嘗試在重定向後添加return語句,以便它不再向response添加更多內容。

response.sendRedirect(LOGOUT_RESOURCE); 
    return; 

The server has already finished writing the response header and is writing the body of the content, and which point you are trying to write more to the header - of course it cant rewind.

+0

仍然沒有工作:/ –

+0

可以請張貼'stacktrace'? –

+0

它是:http://pastebin.com/Z7a5n8kj –

相關問題