📄 mbasicauthenticationlogout.java
字号:
package net.jumperz.app.MGuardian.plugin;
import java.io.*;
import java.util.regex.*;
import java.util.*;
import net.jumperz.net.*;
import net.jumperz.net.exception.MHttpIOException;
import net.jumperz.util.*;
import net.jumperz.security.MBlowfishCipher;
import net.jumperz.security.MTokenGenerator;
public class MBasicAuthenticationLogout
extends MGuardianPlugin
{
private final static String REALM_ID_PARAM_NAME = "guardian_ba_realm_id";
private final static String LOGOUT_PARAM_NAME = "guardian_ba_logout";
private final static String REALM_PARAM_NAME = "guardian_ba_realm";
private final static String REDIRECTED_PARAM_NAME = "guardian_ba_redirected";
private final static String LAST_VISIT_PARAM_NAME = "guardian_ba_last_visit";
private final static String DEFAULT_TIMEOUT = "30"; // minute;
private final static String DEFAULT_KEY = "613925036696971b7304ff84ead72437"; // 16 characters = 128 bit
private final static String DEFAULT_FORCECOOKIE = "true";
private MTokenGenerator tokenGenerator;
private long timeout;
private String key;
private MBlowfishCipher cipher;
private boolean forceCookie;
// --------------------------------------------------------------------------------
public void startup()
throws IOException
{
timeout = Integer.parseInt( control.getProperty( "basicAuthenticationLogout.timeout", DEFAULT_TIMEOUT ) );
key = control.getProperty( "basicAuthenticationLogout.key", DEFAULT_KEY );
String forceCookieStr = control.getProperty( "basicAuthenticationLogout.forceCookie", DEFAULT_FORCECOOKIE );
forceCookie = MStringUtil.meansTrue( forceCookieStr );
try
{
tokenGenerator = new MTokenGenerator();
cipher = new MBlowfishCipher( key );
}
catch( Exception e )
{
e.printStackTrace();
throw new IOException( e.getMessage() );
}
}
//--------------------------------------------------------------------------------
public Map execute( Map sessionInfo )
throws IOException
{
String arg = ( String )sessionInfo.get( "arg" );
try
{
if( arg.indexOf( "request" ) == 0 )
{
return processRequest( sessionInfo, arg );
}
else if( arg.equals( "response" ) )
{
return processResponse( sessionInfo );
}
else if( arg.indexOf( "logout" ) == 0 )
{
return processLogout( sessionInfo, arg );
}
}
catch( IOException e )
{
Map pluginResult = new HashMap();
pluginResult.put( "block", new Boolean( true ) );
pluginResult.put( "log", new Boolean( true ) );
pluginResult.put( "message", e.getMessage() );
return pluginResult;
}
catch( Exception e )
{
e.printStackTrace();
return null;
}
return null;
}
// --------------------------------------------------------------------------------
private Map processLogout( Map sessionInfo, String arg )
throws IOException
{
String[] args = arg.split( "\\s" );
String bodyStr = "You have been successfully logout.";
if( args.length >= 2 )
{
String fileName = arg.substring( arg.indexOf( args[ 1 ] ) );
bodyStr = MStringUtil.loadStrFromFile( fileName );
}
MHttpResponse response = new MHttpResponse();
response.setStatusLine( "HTTP/1.0 200 OK" );
response.setBody( bodyStr );
response.addHeaderValue( "Set-Cookie", LOGOUT_PARAM_NAME + "=1;Path=/" );
response.addHeaderValue( "Set-Cookie", REALM_ID_PARAM_NAME + "=0;Path=/" );
response.setHeaderValue( "Content-Length", response.getBodyAsString().length() + "" );
response.setHeaderValue( "Pragma", "no-cache" );
response.setHeaderValue( "Cache-Control", "no-cache" );
Map pluginResult = new HashMap();
pluginResult.put( "response", response );
pluginResult.put( "pass", new Boolean( true ) );
return pluginResult;
}
// --------------------------------------------------------------------------------
private Map processResponse( Map sessionInfo )
throws IOException
{
MHttpResponse response = ( MHttpResponse )sessionInfo.get( "response" );
MHttpRequest request = ( MHttpRequest )sessionInfo.get( "request" );
if( response == null )
{
throw new IOException( "Response is null." );
}
String realmId = getRealmIdFromRequest( request );
String realmCookie = getCookieValue( request, REALM_ID_PARAM_NAME );
String uriStr = request.getUri();
if( response.getStatusCode() == 401 )
{
setLastVisit( response );
String wwwauth = response.getHeaderValue( "WWW-Authenticate" );
String realm = "";
if( wwwauth != null )
{
realm = MRegEx.getMatch( "realm=\"(.*)\"", wwwauth );
}
if( uriStr.indexOf( REALM_ID_PARAM_NAME ) > -1 && ( realmCookie.equals( realmId + "401" ) ) )
{
response.setHeaderValue( "WWW-Authenticate", "Basic realm=\"" + realm + " " + realmId + "\"" );
}
else if( uriStr.indexOf( REALM_ID_PARAM_NAME ) > -1 && realmCookie.equals( "" ) )
{
if( forceCookie )
{
response = new MHttpResponse();
response.setStatusLine( "HTTP/1.0 403 Forbidden" );
String bodyStr = "Please enable Cookies";
response.setBody( bodyStr );
response.setHeaderValue( "Content-Type", "text/plain" );
response.setHeaderValue( "Content-Length", bodyStr );
}
}
else
{
realmId = tokenGenerator.getToken();
String host = request.getHeaderValue( "Host" );
String protocol = ( String )sessionInfo.get( "protocol" );
if( protocol.equals( "HTTPS" ) )
{
protocol = "https";
}
else
{
protocol = "http";
}
uriStr = uriStr.replaceFirst( "[&]?" + REALM_ID_PARAM_NAME + "=[a-fA-F0-9]*", "" );
MRequestUri ru = new MRequestUri( uriStr );
String query = ru.getQuery();
if( query.equals( "" ) )
{
query = REALM_ID_PARAM_NAME + "=" + realmId;
}
else
{
query += "&" + REALM_ID_PARAM_NAME + "=" + realmId;
}
ru.setQuery( query );
String location = protocol + "://" + host + ru.toString();
response.setStatusLine( "HTTP/1.0 307 Temporary Redirect" );
response.setHeaderValue( "Location", location );
response.removeHeaderValue( "WWW-Authenticate" );
response.addHeaderValue( "Set-Cookie", REALM_ID_PARAM_NAME + "=" + realmId + ";Path=/" );
response.addHeaderValue( "Set-Cookie", LOGOUT_PARAM_NAME + "=1;Path=/" );
response.addHeaderValue( "Set-Cookie", REALM_PARAM_NAME + "=" + realm + ";Path=/" );
}
}
else
{
if( uriStr.indexOf( REALM_ID_PARAM_NAME ) > 0 )
{
//successfully login
response.addHeaderValue( "Set-Cookie", LOGOUT_PARAM_NAME + "=0;Path=/" );
response.addHeaderValue( "Set-Cookie", REALM_ID_PARAM_NAME + "=0;Path=/" );
}
if( request.headerExists( "Authorization" ) )
{
setLastVisit( response );
}
}
return null;
}
// --------------------------------------------------------------------------------
private void setLastVisit( MHttpResponse response )
throws IOException
{
byte[] encByte = cipher.encrypt( MStringUtil.getBytes( Long.toHexString( System.currentTimeMillis() ) ) );
String lastVisit = MStringUtil.byteToHexString( encByte );
response.addHeaderValue( "Set-Cookie", LAST_VISIT_PARAM_NAME + "=" + lastVisit + ";Path=/" );
}
// --------------------------------------------------------------------------------
private String getRealmIdFromRequest( MHttpRequest request )
{
String realmParam = request.getParameterValue( REALM_ID_PARAM_NAME );
if( Pattern.matches( "^[a-fA-F0-9]+$", realmParam ) )
{
return realmParam;
}
else
{
return tokenGenerator.getToken();
}
}
// --------------------------------------------------------------------------------
private Map processRequest( Map sessionInfo, String arg )
throws IOException
{
String[] args = arg.split( "\\s" );
String needAuthFileName = "";
String bodyStr = "Authorization Required.";
if( args.length < 2 )
{
}
else
{
bodyStr = MStringUtil.loadStrFromFile( args[ 1 ] );
}
MHttpRequest request = ( MHttpRequest )sessionInfo.get( "request" );
String uriStr = request.getUri();
String logoutCookie = getCookieValue( request, LOGOUT_PARAM_NAME );
String realmId = getRealmIdFromRequest( request );
String realmCookie = getCookieValue( request, REALM_ID_PARAM_NAME );
String realm = getCookieValue( request, REALM_PARAM_NAME );
if( uriStr.indexOf( REDIRECTED_PARAM_NAME ) > -1 )
{
MHttpResponse response = new MHttpResponse();
response.setStatusLine( "HTTP/1.0 200 OK" );
response.setHeaderValue( "Content-Length", bodyStr.length() + "" );
response.addHeaderValue( "Set-Cookie", REALM_ID_PARAM_NAME + "=0;Path=/" );
response.setBody( bodyStr );
Map pluginResult = new HashMap();
pluginResult.put( "response", response );
pluginResult.put( "pass", new Boolean( true ) );
return pluginResult;
}
//check timeout
if( request.headerExists( "Authorization" ) )
{
String lastVisitStr = getCookieValue( request, LAST_VISIT_PARAM_NAME );
if( lastVisitStr.length() > 0 )
{
byte[] encByte = MStringUtil.hexStringToByteArray( lastVisitStr );
byte[] decByte = cipher.decrypt( encByte );
lastVisitStr = MStringUtil.byteArrayToString( decByte );
long lastVisit = 0;
try
{
lastVisit = Long.parseLong( lastVisitStr, 16 );
}
catch( NumberFormatException ignored )
{
ignored.printStackTrace();
}
long now = System.currentTimeMillis();
// if( ( now - lastVisit ) > ( 10 * 1000 ) ) //10 seconds
long passed = now - lastVisit;
long l = ( long )( timeout * 60 * 1000 );
if( passed > l )
{
//timeout
request.removeHeaderValue( "Authorization" );
}
}
else
{
//disabling cookies
if( forceCookie )
{
request.removeHeaderValue( "Authorization" );
}
}
}
if( uriStr.indexOf( REALM_ID_PARAM_NAME ) == -1 )
{
if( logoutCookie.equals( "1" ) )
{
//if logout=1, remove the authorization header
request.removeHeaderValue( "Authorization" );
}
return null;
}
else
{
if( logoutCookie.equals( "0" ) )
{
return null;
}
String redirectUri = uriStr.replaceFirst( REALM_ID_PARAM_NAME + "=[a-fA-F0-9]*", REDIRECTED_PARAM_NAME + "=1" );
if( realmCookie.equals( "" ) )
{
//disabling cookies
if( forceCookie )
{
MHttpResponse response = new MHttpResponse();
response.setStatusLine( "HTTP/1.0 403 Forbidden" );
bodyStr = "Please enable Cookies";
response.setBody( bodyStr );
response.setHeaderValue( "Content-Type", "text/plain" );
response.setHeaderValue( "Content-Length", bodyStr.length() + "" );
Map pluginResult = new HashMap();
pluginResult.put( "response", response );
pluginResult.put( "pass", new Boolean( true ) );
return pluginResult;
}
else
{
return null;
}
}
else if( realmId.equals( realmCookie ) )
{
if( logoutCookie.equals( "1" ) )
{
return return401( realmId, realm, redirectUri );
}
else
{
return null;
}
}
else if( ( realmId + "401" ).equals( realmCookie ) )
{
return null;
}
else
{
return return401( realmId, realm, redirectUri );
}
}
}
// --------------------------------------------------------------------------------
private String getCookieValue( MHttpRequest request, String name )
throws IOException
{
List cookieList = request.getCookieValueList( name );
if( cookieList.size() > 1 )
{
throw new MHttpIOException( "Cookie_Monster_Found." );
}
String cookie = request.getCookieValue( name );
if( cookie.indexOf( '"' ) > -1 )
{
throw new MHttpIOException( "Invalid_Cookie_Value." );
}
return cookie;
}
// --------------------------------------------------------------------------------
private Map return401( String realmId, String realm, String redirectUri )
throws IOException
{
MHttpResponse response = new MHttpResponse();
response.setStatusLine( "HTTP/1.0 401 Authorization Required" );
response.setHeaderValue( "WWW-Authenticate", "Basic realm=\"" + realm + " " + realmId + "\"" );
response.addHeaderValue( "Set-Cookie", REALM_ID_PARAM_NAME + "=" + realmId + "401;Path=/" );
response.addHeaderValue( "Set-Cookie", LOGOUT_PARAM_NAME + "=1;Path=/" );
String bodyStr = "<META HTTP-EQUIV=\"Refresh\" CONTENT=\"0;URL=" + redirectUri + "\">";
response.setHeaderValue( "Content-Length", bodyStr.length() + "" );
response.setBody( bodyStr );
Map pluginResult = new HashMap();
pluginResult.put( "response", response );
pluginResult.put( "pass", new Boolean( true ) );
return pluginResult;
}
//--------------------------------------------------------------------------------
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -