📄 spnegohandler.java
字号:
/**
* SpnegoHandler.java
*
* Copyright 2009 Tidal Software. All rights reserved.
*
* Revision History:
* Date Name Action
* ------------------------------------------------
* Feb 12, 2009 wayne Created
*/
package com.tidalsoft.webconsole.sso.filter;
import java.io.*;
import javax.servlet.http.*;
import jcifs.ntlmssp.*;
import org.apache.commons.codec.binary.*;
import org.apache.commons.logging.*;
import com.tidalsoft.webconsole.sso.*;
import com.tidalsoft.webconsole.sso.UserAuthResult.*;
public class SpnegoHandler implements Serializable {
private static final long serialVersionUID = -6839194932114110996L;
final static Log logger = LogFactory.getLog(SpnegoHandler.class);
/**
* The server header (WWW-Authenticate).
*/
private final static String HEADER_WWW_AUTHENTICATE = "WWW-Authenticate";
/**
* The client header (Authoriation).
*/
private final static String HEADER_AUTHORIZATION = "Authorization";
/**
* The prefix used by SPNEGO before the Base64 encoded GSS-API token
* (Negotiate).
*/
private final static String NEG_TOKEN = "Negotiate";
/**
* The prefix used by Kerberos
*/
private final static String KERBEROS_TOKEN = "Kerberos";
/**
* The prefix used by NTLM
*/
private final static String NTLM_TOKEN = "NTLM";
/**
* Result return from ServerAction
*/
private UserAuthResult result = new UserAuthResult();
public UserAuthResult getResult() {
return result;
}
/**
* Authenticate user and set result in response string
*
* @param request
* @param response
* @return true for authenticate succeed, false for authenticate failed.
* @throws IOException
*/
public void authenticate(HttpServletRequest request,
HttpServletResponse response) throws IOException {
logger.debug("Entering Spnego authentication remote address: "
+ request.getRemoteAddr());
String authorization = request.getHeader(HEADER_AUTHORIZATION);
if (authorization == null) {
// if it is the first step, no negotiate token, return response directly
response.addHeader(HEADER_WWW_AUTHENTICATE, NEG_TOKEN);
// response.addHeader(HEADER_WWW_AUTHENTICATE, KERBEROS_TOKEN);
result.setState(State.NEGOTIATING);
}else if (authorization.startsWith(NTLM_TOKEN)) {
// if the IE select NTLM authentication,redirect to login page
result.setState(State.FAILED);
}else if(authorization.startsWith(KERBEROS_TOKEN)) {
String s = authorization.substring(KERBEROS_TOKEN.length() + 1);
byte[] token = Base64.decodeBase64(s.getBytes());
byte[] replyToken = null;
replyToken = kerberosAuth(token, Krb5LoginAuthAction.KRB5_OID);
if (replyToken != null) {
String responseToken = KERBEROS_TOKEN + " " + new String(new Base64().encode(replyToken));
response.setHeader(HEADER_WWW_AUTHENTICATE, responseToken);
}
}else if(authorization.startsWith(NEG_TOKEN)){
String s = authorization.substring(NEG_TOKEN.length() + 1);
byte[] token = Base64.decodeBase64(s.getBytes());
byte[] replyToken = null;
if(token[0]=='N')
replyToken = ntlmAuth(token);
else
replyToken = kerberosAuth(token, Krb5LoginAuthAction.SPNEGO_OID);
if (replyToken != null) {
String responseToken = NEG_TOKEN + " " + new String(new Base64().encode(replyToken));
response.setHeader(HEADER_WWW_AUTHENTICATE, responseToken);
}
}
}
/**
* Pseudo NTLM authentication, generate a invalid type2 message to client, not do real NTLM authentication
* @param token
* @return
* @throws IOException
*/
public byte[] ntlmAuth(byte[] token) throws IOException {
logger.debug("Client request NTLM authentication");
if (token[8] == 1) {
Type1Message type1 = new Type1Message(token);
byte[] challenge = new byte[8];
Type2Message type2 = new Type2Message(type1, challenge, null);
result.setState(State.NTLM);
return type2.toByteArray();
} else if (token[8] == 3) {
Type3Message type3 = new Type3Message(token);
result.setState(State.NTLM_PASS);
return null;
}else
return null;
}
/**
* Kerberos Authentication, oid should be SPNEGO for SPNEGO authentication
* also support Kerberos authentication, but IE do not support it, so it won't work
*
* @param token
* @param oid
* @return
* @throws IOException
*/
public byte[] kerberosAuth(byte[] token, String oid) throws IOException {
logger.debug("Client select Kerberos.");
// check whether authentication request is valid
if (token[0] != 96) {
logger.warn("Invalid authentication request.");
return null;
}
try {
Krb5LoginAuthAction action = new Krb5LoginAuthAction(token,oid);
result = (UserAuthResult) WebconsoleJaas.getInstance().action(action);
} catch (Exception e) {
e.printStackTrace();
result.setState(State.FAILED);
return null;
}
return result.getReplyToken();
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -