我已經使用sourceforge spnego project實施了SSO身份驗證。使用sourceforge spnego對照活動目錄進行SSO身份驗證
這是我第一次實施任何形式的servlet身份驗證的,所以我可能會丟失一些非常基本的身份驗證或者說,我只是不知道關於servlet ...
我使用自帶打包SpnegoHttpFilter
將過濾器鏈頂部的庫設置爲不覆蓋,然後在過濾器鏈中將我自己的過濾器QueryFilter
包括在內,以便我可以將登錄名映射到數據庫user_id。在HttpRequest通過SpnegoHttpFilter
之後,登錄名稱(Windows域上的NT用戶ID)由getRemoteUser
調用返回,這似乎都工作正常。
我自己的過濾器QueryFilter
正在做它應該做的事情,它正在將登錄名正確映射到數據庫user_id。我也有這個過濾器的邏輯拒絕未通過我的身份驗證的請求,這也工作得很好:當我模擬未經授權的請求時,此過濾器將停止它,並且它永遠不會將它傳遞給servlet。
麻煩的是,所有請求返回爲401(HTTP請求狀態未授權),即使它們通過認證,在我QueryFilter
並執行該servlet完全罰款。
我嘗試在我自己的過濾器中使用下面的代碼明確地定義響應爲200(HTTP請求狀態正常):但是這並沒有改變任何東西。
要隔離該問題,我完全刪除了HttpSpnegoFilter
,並將一個硬編碼的登錄名(NT用戶標識)傳遞到我的QueryFilter
。這工作正常,答覆不再401(未經授權)。
這意味着打包的HttpSpnegoFilter
以某種方式將請求轉換爲Unauthorized
。並且以一種不會改變的方式進行,當我說這實際上是OK的時候。
有誰知道我可以如何設置響應頭以200(確定)返回使用這個spnego sourceforge項目?
從web應用程序的web.xml
我的全過濾器鏈是下面,提到我用的包裝HttpSpnegoFilter
在鏈的頂部,然後我自己的過濾器(這似乎是在做它的工作正常)右下方:
<filter>
<filter-name>SpnegoHttpFilter</filter-name>
<filter-class>net.sourceforge.spnego.SpnegoHttpFilter</filter-class>
<init-param>
<param-name>spnego.allow.basic</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<param-name>spnego.allow.delegation</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<param-name>spnego.allow.localhost</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<param-name>spnego.allow.unsecure.basic</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<param-name>spnego.login.client.module</param-name>
<param-value>spnego-client</param-value>
</init-param>
<init-param>
<param-name>spnego.krb5.conf</param-name>
<param-value>krb5.conf</param-value>
</init-param>
<init-param>
<param-name>spnego.login.conf</param-name>
<param-value>login.conf</param-value>
</init-param>
<init-param>
<param-name>spnego.preauth.username</param-name>
<param-value>myADServicePrincipal</param-value>
</init-param>
<init-param>
<param-name>spnego.preauth.password</param-name>
<param-value>myADServicePrincipalPassword</param-value>
</init-param>
<init-param>
<param-name>spnego.login.server.module</param-name>
<param-value>spnego-server</param-value>
</init-param>
<init-param>
<param-name>spnego.prompt.ntlm</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<param-name>spnego.logger.level</param-name>
<param-value>1</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>SpnegoHttpFilter</filter-name>
<servlet-name>QueryServlet</servlet-name>
</filter-mapping>
<filter>
<filter-name>QueryFilter</filter-name>
<filter-class>my.package.name.QueryFilter</filter-class>
<init-param>
<param-name>query.permission.list</param-name>
<param-value>getQueryPermission</param-value>
</init-param>
<init-param>
<param-name>remote.user.column</param-name>
<param-value>nt_user_id</param-value>
</init-param>
<init-param>
<param-name>user.id.column</param-name>
<param-value>user_id</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>QueryFilter</filter-name>
<servlet-name>QueryServlet</servlet-name>
</filter-mapping>
我也包括我QueryFilter
低於(儘管它似乎並沒有對我的問題有任何影響,因爲它的工作原理罰款本身,當我不使用SpnegoHttpFilter
類和完整性只是傳遞一個硬編碼的NT用戶ID)。在倒數第二行是我明確地告訴響應是OK
無濟於事:
import java.io.IOException;
import java.util.Map;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public final class QueryFilter implements Filter {
private MapListDAO myMapListDAO;
private String myPermissionsList;
private String myRemoteUserColumn;
private String myUserIdColumn;
@Override
public void init(final FilterConfig filterConfig) throws ServletException {
myMapListDAO = Config.getInstance(filterConfig.getServletContext()).getMapListDAO();
myPermissionsList = filterConfig.getInitParameter("query.permission.list");
myRemoteUserColumn = filterConfig.getInitParameter("remote.user.column");
myUserIdColumn = filterConfig.getInitParameter("user.id.column");
}
@Override
public void destroy() {
// TODO ...?
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
HttpServletRequest httpRequest = (HttpServletRequest) request;
HttpServletResponse httpResponse = (HttpServletResponse) response;
String queryName = request.getParameter("queryName");
// because I have SpnegoHttpFilter earlier in my filter chain
// this returns the NT User ID (what the user logged in to the domain with)
String remoteUser = httpRequest.getRemoteUser();
Map<String, Object> queryPermissions = myMapListDAO.getEntry(myPermissionsList, myRemoteUserColumn, remoteUser);
// if there is no queryName defined
if (null == queryName) {
httpResponse.sendError(HttpServletResponse.SC_BAD_REQUEST,
"Missing queryName parameter.");
return;
}
// if this query is protected perform the gauntlet
if (myMapListDAO.getList(myPermissionsList).get(0).containsKey(queryName)) {
// if there is no remoteUser
if (null == remoteUser || remoteUser.isEmpty()) {
httpResponse.sendError(HttpServletResponse.SC_UNAUTHORIZED,
"Cannot get remoteUser.");
return;
}
// if the remoteUser does not have any queryPermissions
if (null == queryPermissions) {
httpResponse.sendError(HttpServletResponse.SC_UNAUTHORIZED,
"Cannot find queryPermissions for " + remoteUser + ".");
return;
}
// if this remoteUser does not have permission to execute the queryName
if ((Boolean) queryPermissions.get(queryName)) {
httpResponse.sendError(HttpServletResponse.SC_UNAUTHORIZED,
"The remoteUser: " + remoteUser + " does not have permission to access queryName: " + queryName + ".");
return;
}
}
// attempt to add the userId to this request as an attribute we can get later
if (null != queryPermissions) {
httpRequest.setAttribute("userId", String.valueOf(queryPermissions.get(myUserIdColumn)));
}
// continue to servlet
httpResponse.setStatus(HttpServletResponse.SC_OK);
chain.doFilter(request, response);
}
}
// attempt to add the userId to this request as an attribute we can get later
if (null != queryPermissions) {
httpRequest.setAttribute("userId", String.valueOf(queryPermissions.get(myUserIdColumn)));
}
// continue to servlet
httpResponse.setStatus(HttpServletResponse.SC_OK);
chain.doFilter(request, response);
}
}