ntlmsessionvalidator.java
来自「jetspeed源代码」· Java 代码 · 共 298 行
JAVA
298 行
/*
* Copyright 2000-2004 The Apache Software Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.jetspeed.modules.actions;
// JDK stuff
import java.util.Locale;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
// Turbine APIs
import org.apache.turbine.util.RunData;
import org.apache.turbine.services.resources.TurbineResources;
import org.apache.turbine.services.localization.LocalizationService;
// Jetspeed APIs
import org.apache.jetspeed.om.security.JetspeedUser;
import org.apache.jetspeed.services.JetspeedSecurity;
import org.apache.jetspeed.services.logging.JetspeedLogFactoryService;
import org.apache.jetspeed.services.logging.JetspeedLogger;
import org.apache.jetspeed.services.security.LoginException;
import org.apache.jetspeed.services.rundata.JetspeedRunData;
import org.apache.jetspeed.util.ServiceUtil;
import org.apache.jetspeed.services.customlocalization.CustomLocalizationService;
import org.apache.jetspeed.services.security.UnknownUserException;
import org.apache.jetspeed.services.security.JetspeedSecurityCache;
/**
* Just like org.apache.turbine.modules.actions.sessionvalidator.TemplateSessionValidator except:
* <ul>
* <li> it doesn't check the session_access_counter
* <li> it automatically logs the user in based on currently authenticated nt user
* <li> expects a JetspeedRunData object and put there the additionnal jetspeed properties
* </ul>
* <B>Usage of this session validator is limited to Windows NT/2000 and MS Internet Explorer.</B>
* <P>
* To activate this session validator, set <CODE>action.sessionvalidator</CODE> in tr.props to
* <code>NTLMSessionValidator</code>.
* </P>
* <P>
* When this session validator is active, the following algorithm is used to display appropriate psml:
* <pre>
* Check authentication status
* If user is not authenticated to machine running the portal
* Pop the standard login box
* If user passes authentication
* Attempt to retrieve matching user profile
* If matching profile found
* Render the profile
* Else
* Retrieve and render anonymous profile
* End
* Else If authentication fails
* Keep prompting for login information
* Else If the user cancels the login box
* Retrieve and render anonymous profile
* End
* Else
* Attempt to retrieve matching user profile
* If matching profile found
* Render the profile
* Else
* Retrieve and render anonymous profile
* End
* End
* </pre>
* </P>
* <P>
* Optionally, certain characters may be removed from the username before it's passed to the
* JetspeedSecurity. These characters may be specified by setting <CODE>NTLMSessionValidator.chars.to.remove</CODE>
* property. For example, if invalid characters list is '#@$', username '#user1' will be returned as 'user1'.
* </P>
*
* @author <a href="mailto:morciuch@apache.org">Mark Orciuch</a>
* @version $Id: NTLMSessionValidator.java,v 1.6 2004/02/23 02:59:06 jford Exp $
* @see org.apache.turbine.modules.actions.sessionvalidator.TemplateSessionValidator
* @see http://www.innovation.ch/java/ntlm.html
* @since 1.4b5
*/
public class NTLMSessionValidator extends TemplateSessionValidator
{
private static final String INVALID_CHARS_KEY = "NTLMSessionValidator.chars.to.remove";
private String invalidChars = org.apache.jetspeed.services.resources.JetspeedResources.getString(INVALID_CHARS_KEY, null);
private static final byte z = 0;
private static final byte[] msg1 = {(byte) 'N', (byte) 'T', (byte) 'L', (byte) 'M', (byte) 'S', (byte) 'S', (byte) 'P',
z, (byte) 2, z, z, z, z, z, z, z, (byte) 40, z, z, z,
(byte) 1, (byte) 130, z, z, z, (byte) 2, (byte) 2,
(byte) 2, z, z, z, z, z, z, z, z, z, z, z, z};
private static final String encodedMsg1 = "NTLM " + new sun.misc.BASE64Encoder().encodeBuffer(msg1).trim();
/**
* Static initialization of the logger for this class
*/
private static final JetspeedLogger logger = JetspeedLogFactoryService.getLogger(NTLMSessionValidator.class.getName());
/**
* Execute the action.
*
* @param data Turbine information.
* @exception Exception, a generic exception.
*/
public void doPerform(RunData data) throws Exception
{
//first, invoke our superclass action to make sure
//we follow Turbine evolutions
//FIXME: if the user is not found (this can happen, for instance,
// if the anonymous user is not in the DB), it throws a terrible exception
// in the user's face
super.doPerform(data);
JetspeedUser user = (JetspeedUser) data.getUser();
// get remote user from ntlm
String userName = this.getRemoteUser(data);
if ((user == null || !user.hasLoggedIn()))
{
if (userName != null && userName.length() > 0)
{
byte[] temp = userName.getBytes();
StringBuffer buffer = new StringBuffer();
for (int i = 0; i < temp.length; i++)
{
if (temp[i] != 0)
{
if (invalidChars == null || invalidChars.indexOf((int) temp[i]) < 0)
{
buffer.append((char) temp[i]);
}
}
}
userName = buffer.toString();
try
{
user = JetspeedSecurity.getUser(userName);
data.setUser(user);
user.setHasLoggedIn(new Boolean(true));
user.updateLastLogin();
data.save();
if (JetspeedSecurityCache.getAcl(userName) == null)
{
JetspeedSecurityCache.load(userName);
}
logger.info("NTLMSessionValidator: automatic login using [" + userName + "]");
}
catch (LoginException noSuchUser)
{
//user not found - ignore it - they will not be logged in automatically
}
catch (UnknownUserException unknownUser)
{
//user not found - ignore it - they will not be logged in automatically
if (logger.isWarnEnabled())
{
logger.warn("NTLMSessionValidator: username [" + userName + "] does not exist or authentication failed, "
+ "redirecting to anon profile");
}
}
}
}
// now, define Jetspeed specific properties, using the customized
// RunData properties
JetspeedRunData jdata = null;
try
{
jdata = (JetspeedRunData) data;
}
catch (ClassCastException e)
{
logger.error("The RunData object does not implement the expected interface, "
+ "please verify the RunData factory settings");
return;
}
String language = (String) data.getRequest().getParameter("js_language");
if (null != language)
{
user.setPerm("language", language);
}
// Get the locale store it in the user object
CustomLocalizationService locService =
(CustomLocalizationService) ServiceUtil.getServiceByName(LocalizationService.SERVICE_NAME);
Locale locale = locService.getLocale(data);
if (locale == null)
{
locale = new Locale(TurbineResources.getString("locale.default.language", "en"),
TurbineResources.getString("locale.default.country", "US"));
}
data.getUser().setTemp("locale", locale);
// if a portlet is referenced in the parameters request, store it
// in the RunData object
String paramPortlet = jdata.getParameters().getString("js_peid");
if (paramPortlet != null && paramPortlet.length() > 0)
{
jdata.setJs_peid(paramPortlet);
}
}
/**
* This session validator does not require a new session for each request
*
* @param data
* @return
*/
public boolean requiresNewSession(RunData data)
{
return false;
}
/**
* Extracts user name from http headers
*
* @param data
* @return
* @exception Exception
*/
private String getRemoteUser(RunData data) throws Exception
{
HttpServletRequest request = data.getRequest();
HttpServletResponse response = data.getResponse();
if (data.getUser().hasLoggedIn() && request.getMethod().equalsIgnoreCase("get"))
{
return data.getUser().getUserName();
}
String auth = request.getHeader("Authorization");
if (auth == null)
{
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
response.setHeader("WWW-Authenticate", "NTLM");
response.flushBuffer();
return null;
}
if (auth.startsWith("NTLM "))
{
byte[] msg = new sun.misc.BASE64Decoder().decodeBuffer(auth.substring(5));
int off = 0, length, offset;
if (msg[8] == 1)
{
response.setHeader("WWW-Authenticate", encodedMsg1);
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
return null;
}
else if (msg[8] == 3)
{
if (data.getUser().hasLoggedIn())
{
return data.getUser().getUserName();
}
off = 30;
//length = msg[off + 17] * 256 + msg[off + 16];
//offset = msg[off + 19] * 256 + msg[off + 18];
//String remoteHost = new String(msg, offset, length);
//length = msg[off + 1] * 256 + msg[off];
//offset = msg[off + 3] * 256 + msg[off + 2];
//String domain = new String(msg, offset, length);
length = msg[off + 9] * 256 + msg[off + 8];
offset = msg[off + 11] * 256 + msg[off + 10];
String username = new String(msg, offset, length);
return username;
}
}
return null;
}
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?