⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 spnegohandler.java

📁 JAAS 例子代码
💻 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 + -