remove unused module
git-svn-id: https://svn.apache.org/repos/asf/archiva/redback/redback-core/trunk@1310470 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
ba7e6d648a
commit
ebb3032c69
|
@ -56,7 +56,6 @@
|
||||||
<module>redback-common-integrations</module>
|
<module>redback-common-integrations</module>
|
||||||
<module>redback-rest</module>
|
<module>redback-rest</module>
|
||||||
<module>redback-struts2</module>
|
<module>redback-struts2</module>
|
||||||
<module>redback-jee</module>
|
|
||||||
<module>redback-jsecurity</module>
|
<module>redback-jsecurity</module>
|
||||||
<module>redback-integrations-security</module>
|
<module>redback-integrations-security</module>
|
||||||
</modules>
|
</modules>
|
||||||
|
|
|
@ -1,34 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<!--
|
|
||||||
~ Licensed to the Apache Software Foundation (ASF) under one
|
|
||||||
~ or more contributor license agreements. See the NOTICE file
|
|
||||||
~ distributed with this work for additional information
|
|
||||||
~ regarding copyright ownership. The ASF licenses this file
|
|
||||||
~ to you 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.
|
|
||||||
-->
|
|
||||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
|
||||||
<modelVersion>4.0.0</modelVersion>
|
|
||||||
<parent>
|
|
||||||
<groupId>org.codehaus.redback</groupId>
|
|
||||||
<artifactId>redback-integrations</artifactId>
|
|
||||||
<version>1.5-SNAPSHOT</version>
|
|
||||||
</parent>
|
|
||||||
<artifactId>redback-jee</artifactId>
|
|
||||||
<name>Redback :: Integration :: J(2)EE</name>
|
|
||||||
<packaging>pom</packaging>
|
|
||||||
|
|
||||||
<modules>
|
|
||||||
<module>redback-jee-web-integration</module>
|
|
||||||
</modules>
|
|
||||||
</project>
|
|
|
@ -1,54 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<!--
|
|
||||||
~ Licensed to the Apache Software Foundation (ASF) under one
|
|
||||||
~ or more contributor license agreements. See the NOTICE file
|
|
||||||
~ distributed with this work for additional information
|
|
||||||
~ regarding copyright ownership. The ASF licenses this file
|
|
||||||
~ to you 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.
|
|
||||||
-->
|
|
||||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
|
||||||
<modelVersion>4.0.0</modelVersion>
|
|
||||||
<parent>
|
|
||||||
<groupId>org.codehaus.redback</groupId>
|
|
||||||
<artifactId>redback-jee</artifactId>
|
|
||||||
<version>1.5-SNAPSHOT</version>
|
|
||||||
</parent>
|
|
||||||
<artifactId>redback-jee-web-integration</artifactId>
|
|
||||||
<name>Redback :: Integration :: J(2)EE Web Integration</name>
|
|
||||||
<packaging>jar</packaging>
|
|
||||||
|
|
||||||
<dependencies>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.springframework</groupId>
|
|
||||||
<artifactId>spring-context-support</artifactId>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>javax.annotation</groupId>
|
|
||||||
<artifactId>jsr250-api</artifactId>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>javax.servlet</groupId>
|
|
||||||
<artifactId>servlet-api</artifactId>
|
|
||||||
<scope>provided</scope>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.codehaus.redback</groupId>
|
|
||||||
<artifactId>redback-system</artifactId>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>commons-codec</groupId>
|
|
||||||
<artifactId>commons-codec</artifactId>
|
|
||||||
</dependency>
|
|
||||||
</dependencies>
|
|
||||||
</project>
|
|
|
@ -1,80 +0,0 @@
|
||||||
package org.codehaus.plexus.redback.http;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Licensed to the Apache Software Foundation (ASF) under one
|
|
||||||
* or more contributor license agreements. See the NOTICE file
|
|
||||||
* distributed with this work for additional information
|
|
||||||
* regarding copyright ownership. The ASF licenses this file
|
|
||||||
* to you 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
import java.util.Properties;
|
|
||||||
|
|
||||||
import org.codehaus.plexus.util.StringUtils;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Collection of Utility methods useful in an Http environment.
|
|
||||||
*
|
|
||||||
* @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
|
|
||||||
* @version $Id$
|
|
||||||
* @todo should move this to plexus-utils or plexus-utils-web
|
|
||||||
*/
|
|
||||||
public class HttpUtils
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Convert typical complex header into properties.
|
|
||||||
* <p/>
|
|
||||||
* <p/>
|
|
||||||
* Example:
|
|
||||||
* </p>
|
|
||||||
* <p/>
|
|
||||||
* <code>
|
|
||||||
* realm="Somewhere Over The Rainbow", domain="kansas.co.us", nonce="65743ABCF"
|
|
||||||
* </code>
|
|
||||||
* <p/>
|
|
||||||
* <p>becomes</p>
|
|
||||||
* <p/>
|
|
||||||
* <code>
|
|
||||||
* Map ( "realm", "Somewhere Over The Rainbox" )
|
|
||||||
* Map ( "domain", "kansas.co.us" )
|
|
||||||
* Map ( "nonce", "65743ABCF" )
|
|
||||||
* </code>
|
|
||||||
*
|
|
||||||
* @param rawheader
|
|
||||||
* @param majorDelim
|
|
||||||
* @param subDelim
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
public static Properties complexHeaderToProperties( String rawheader, String majorDelim, String subDelim )
|
|
||||||
{
|
|
||||||
Properties ret = new Properties();
|
|
||||||
|
|
||||||
if ( StringUtils.isEmpty( rawheader ) )
|
|
||||||
{
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
String array[] = StringUtils.split( rawheader, majorDelim );
|
|
||||||
for ( int i = 0; i < array.length; i++ )
|
|
||||||
{
|
|
||||||
// String quotes.
|
|
||||||
String rawelem = StringUtils.replace( array[i], "\"", "" );
|
|
||||||
String parts[] = StringUtils.split( rawelem, subDelim, 2 );
|
|
||||||
|
|
||||||
ret.setProperty( StringUtils.trim( parts[0] ), StringUtils.trim( parts[1] ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,155 +0,0 @@
|
||||||
package org.codehaus.plexus.redback.http.authentication;
|
|
||||||
|
|
||||||
import org.codehaus.plexus.redback.authentication.AuthenticationDataSource;
|
|
||||||
import org.codehaus.plexus.redback.authentication.AuthenticationException;
|
|
||||||
import org.codehaus.plexus.redback.authentication.AuthenticationResult;
|
|
||||||
import org.codehaus.plexus.redback.policy.AccountLockedException;
|
|
||||||
import org.codehaus.plexus.redback.policy.MustChangePasswordException;
|
|
||||||
import org.codehaus.plexus.redback.system.SecuritySession;
|
|
||||||
import org.codehaus.plexus.redback.system.SecuritySystem;
|
|
||||||
import org.codehaus.plexus.redback.users.User;
|
|
||||||
import org.codehaus.plexus.redback.users.UserNotFoundException;
|
|
||||||
import org.codehaus.plexus.util.StringUtils;
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
import javax.inject.Inject;
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
|
||||||
import javax.servlet.http.HttpServletResponse;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* HttpAuthenticator is the workings of an authenticator for http with the session storage abstracted
|
|
||||||
*
|
|
||||||
* @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
|
|
||||||
* @author Andrew Williams
|
|
||||||
* @version $Id$
|
|
||||||
*/
|
|
||||||
public abstract class AbstractHttpAuthenticator
|
|
||||||
implements HttpAuthenticator
|
|
||||||
{
|
|
||||||
protected Logger log = LoggerFactory.getLogger( getClass() );
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
protected SecuritySystem securitySystem;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The Public Face of the Authenticator.
|
|
||||||
*
|
|
||||||
* @throws org.codehaus.plexus.redback.policy.MustChangePasswordException
|
|
||||||
*
|
|
||||||
* @throws org.codehaus.plexus.redback.policy.AccountLockedException
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
protected AuthenticationResult authenticate( AuthenticationDataSource ds, Object session )
|
|
||||||
throws AuthenticationException, AccountLockedException, MustChangePasswordException
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
SecuritySession securitySession = securitySystem.authenticate( ds );
|
|
||||||
|
|
||||||
setSecuritySession( securitySession, session );
|
|
||||||
|
|
||||||
return securitySession.getAuthenticationResult();
|
|
||||||
}
|
|
||||||
catch ( AuthenticationException e )
|
|
||||||
{
|
|
||||||
String msg = "Unable to authenticate user: " + ds;
|
|
||||||
log.info( msg, e );
|
|
||||||
throw new HttpAuthenticationException( msg, e );
|
|
||||||
}
|
|
||||||
catch ( UserNotFoundException e )
|
|
||||||
{
|
|
||||||
log.info( "Login attempt against unknown user: {}", ds );
|
|
||||||
throw new HttpAuthenticationException( "User name or password invalid.", e );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Entry point for a Filter.
|
|
||||||
*
|
|
||||||
* @param request
|
|
||||||
* @param response
|
|
||||||
* @throws org.codehaus.plexus.redback.authentication.AuthenticationException
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public void authenticate( HttpServletRequest request, HttpServletResponse response )
|
|
||||||
throws AuthenticationException
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
AuthenticationResult result = getAuthenticationResult( request, response );
|
|
||||||
|
|
||||||
if ( ( result == null ) || ( !result.isAuthenticated() ) )
|
|
||||||
{
|
|
||||||
throw new HttpAuthenticationException( "You are not authenticated." );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch ( AccountLockedException e )
|
|
||||||
{
|
|
||||||
throw new HttpAuthenticationException( "Your account is locked." );
|
|
||||||
}
|
|
||||||
catch ( MustChangePasswordException e )
|
|
||||||
{
|
|
||||||
throw new HttpAuthenticationException( "You must change your password." );
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
protected abstract Object getSessionValue( Object session, String key );
|
|
||||||
|
|
||||||
protected abstract void setSessionValue( Object session, String key, Object value );
|
|
||||||
|
|
||||||
protected User getSessionUser( Object session )
|
|
||||||
{
|
|
||||||
return (User) getSessionValue( session, SecuritySession.USERKEY );
|
|
||||||
}
|
|
||||||
|
|
||||||
protected boolean isAlreadyAuthenticated( Object session )
|
|
||||||
{
|
|
||||||
User user = getSessionUser( session );
|
|
||||||
|
|
||||||
return ( ( user != null ) && !user.isLocked() );
|
|
||||||
}
|
|
||||||
|
|
||||||
protected SecuritySession getSecuritySession( Object session )
|
|
||||||
{
|
|
||||||
return (SecuritySession) getSessionValue( session, SecuritySession.SESSION_KEY );
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void setSecuritySession( SecuritySession session, Object sessionObj )
|
|
||||||
{
|
|
||||||
setSessionValue( sessionObj, SecuritySession.SESSION_KEY, session );
|
|
||||||
setSessionValue( sessionObj, SecuritySession.USERKEY, session.getUser() );
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void setSessionUser( User user, Object session )
|
|
||||||
{
|
|
||||||
setSessionValue( session, SecuritySession.SESSION_KEY, null );
|
|
||||||
setSessionValue( session, SecuritySession.USERKEY, user );
|
|
||||||
}
|
|
||||||
|
|
||||||
protected String storeDefaultUser( String principal, Object session )
|
|
||||||
{
|
|
||||||
setSessionValue( session, SecuritySession.SESSION_KEY, null );
|
|
||||||
setSessionValue( session, SecuritySession.USERKEY, null );
|
|
||||||
|
|
||||||
if ( StringUtils.isEmpty( principal ) )
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
User user = securitySystem.getUserManager().findUser( principal );
|
|
||||||
setSessionValue( session, SecuritySession.USERKEY, user );
|
|
||||||
|
|
||||||
return user.getPrincipal().toString();
|
|
||||||
|
|
||||||
}
|
|
||||||
catch ( UserNotFoundException e )
|
|
||||||
{
|
|
||||||
log.warn( "Default User '" + principal + "' not found.", e );
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,35 +0,0 @@
|
||||||
package org.codehaus.plexus.redback.http.authentication;
|
|
||||||
|
|
||||||
import org.codehaus.plexus.redback.authentication.AuthenticationException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* HttpAuthenticationException
|
|
||||||
*
|
|
||||||
* @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
|
|
||||||
* @version $Id$
|
|
||||||
*/
|
|
||||||
public class HttpAuthenticationException
|
|
||||||
extends AuthenticationException
|
|
||||||
{
|
|
||||||
|
|
||||||
public HttpAuthenticationException()
|
|
||||||
{
|
|
||||||
super();
|
|
||||||
}
|
|
||||||
|
|
||||||
public HttpAuthenticationException( String message, Throwable cause )
|
|
||||||
{
|
|
||||||
super( message, cause );
|
|
||||||
}
|
|
||||||
|
|
||||||
public HttpAuthenticationException( String message )
|
|
||||||
{
|
|
||||||
super( message );
|
|
||||||
}
|
|
||||||
|
|
||||||
public HttpAuthenticationException( Throwable cause )
|
|
||||||
{
|
|
||||||
super( cause );
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,58 +0,0 @@
|
||||||
package org.codehaus.plexus.redback.http.authentication;
|
|
||||||
|
|
||||||
import org.codehaus.plexus.redback.authentication.AuthenticationException;
|
|
||||||
import org.codehaus.plexus.redback.authentication.AuthenticationResult;
|
|
||||||
import org.codehaus.plexus.redback.policy.AccountLockedException;
|
|
||||||
import org.codehaus.plexus.redback.policy.MustChangePasswordException;
|
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
|
||||||
import javax.servlet.http.HttpServletResponse;
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* HttpAuthenticator
|
|
||||||
*
|
|
||||||
* @author Andrew Williams
|
|
||||||
* @version $Id$
|
|
||||||
*/
|
|
||||||
public interface HttpAuthenticator
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Entry point for a Filter.
|
|
||||||
*
|
|
||||||
* @param request
|
|
||||||
* @param response
|
|
||||||
* @throws AuthenticationException
|
|
||||||
*/
|
|
||||||
void authenticate( HttpServletRequest request, HttpServletResponse response )
|
|
||||||
throws AuthenticationException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Issue a Challenge Response back to the HTTP Client.
|
|
||||||
*
|
|
||||||
* @param request
|
|
||||||
* @param response
|
|
||||||
* @param realmName
|
|
||||||
* @param exception
|
|
||||||
* @throws java.io.IOException
|
|
||||||
*/
|
|
||||||
void challenge( HttpServletRequest request, HttpServletResponse response, String realmName,
|
|
||||||
AuthenticationException exception )
|
|
||||||
throws IOException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Parse the incoming request and return an AuthenticationResult.
|
|
||||||
*
|
|
||||||
* @param request
|
|
||||||
* @param response
|
|
||||||
* @return null if no http auth credentials, or the actual authentication result based on the credentials.
|
|
||||||
* @throws AuthenticationException
|
|
||||||
* @throws org.codehaus.plexus.redback.policy.MustChangePasswordException
|
|
||||||
*
|
|
||||||
* @throws org.codehaus.plexus.redback.policy.AccountLockedException
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
AuthenticationResult getAuthenticationResult( HttpServletRequest request, HttpServletResponse response )
|
|
||||||
throws AuthenticationException, AccountLockedException, MustChangePasswordException;
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,79 +0,0 @@
|
||||||
package org.codehaus.plexus.redback.http.authentication;
|
|
||||||
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import org.codehaus.plexus.redback.authentication.AuthenticationDataSource;
|
|
||||||
import org.codehaus.plexus.redback.authentication.AuthenticationException;
|
|
||||||
import org.codehaus.plexus.redback.authentication.AuthenticationResult;
|
|
||||||
import org.codehaus.plexus.redback.policy.AccountLockedException;
|
|
||||||
import org.codehaus.plexus.redback.policy.MustChangePasswordException;
|
|
||||||
import org.codehaus.plexus.redback.system.SecuritySession;
|
|
||||||
import org.codehaus.plexus.redback.users.User;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* An HttpAuthenticator using a Map for session storage
|
|
||||||
*
|
|
||||||
* @author Andrew Williams
|
|
||||||
* @version $Id$
|
|
||||||
* @since 1.0
|
|
||||||
*/
|
|
||||||
public abstract class MapBasedHttpAuthenticator
|
|
||||||
extends AbstractHttpAuthenticator
|
|
||||||
{
|
|
||||||
|
|
||||||
protected Object getSessionValue( Object session, String key )
|
|
||||||
{
|
|
||||||
if ( !( session instanceof Map ) )
|
|
||||||
{
|
|
||||||
throw new IllegalArgumentException( "The session for a MapBasedAuthenticator must be a java.util.Map" );
|
|
||||||
}
|
|
||||||
|
|
||||||
return ( (Map) session ).get( key );
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void setSessionValue( Object session, String key, Object value )
|
|
||||||
{
|
|
||||||
if ( !( session instanceof Map ) )
|
|
||||||
{
|
|
||||||
throw new IllegalArgumentException( "The session for a MapBasedAuthenticator must be a java.util.Map" );
|
|
||||||
}
|
|
||||||
|
|
||||||
( (Map) session ).put( key, value );
|
|
||||||
}
|
|
||||||
|
|
||||||
public AuthenticationResult authenticate( AuthenticationDataSource ds, Map session )
|
|
||||||
throws AuthenticationException, AccountLockedException, MustChangePasswordException
|
|
||||||
{
|
|
||||||
return super.authenticate( ds, session );
|
|
||||||
}
|
|
||||||
|
|
||||||
public User getSessionUser( Map session )
|
|
||||||
{
|
|
||||||
return super.getSessionUser( session );
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isAlreadyAuthenticated( Map session )
|
|
||||||
{
|
|
||||||
return super.isAlreadyAuthenticated( session );
|
|
||||||
}
|
|
||||||
|
|
||||||
public SecuritySession getSecuritySession( Map session )
|
|
||||||
{
|
|
||||||
return super.getSecuritySession( session );
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setSecuritySession( SecuritySession session, Map sessionObj )
|
|
||||||
{
|
|
||||||
super.setSecuritySession( session, sessionObj );
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setSessionUser( User user, Map session )
|
|
||||||
{
|
|
||||||
super.setSessionUser( user, session );
|
|
||||||
}
|
|
||||||
|
|
||||||
public String storeDefaultUser( String principal, Map session )
|
|
||||||
{
|
|
||||||
return super.storeDefaultUser( principal, session );
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,79 +0,0 @@
|
||||||
package org.codehaus.plexus.redback.http.authentication;
|
|
||||||
|
|
||||||
import javax.servlet.http.HttpSession;
|
|
||||||
|
|
||||||
import org.codehaus.plexus.redback.authentication.AuthenticationDataSource;
|
|
||||||
import org.codehaus.plexus.redback.authentication.AuthenticationException;
|
|
||||||
import org.codehaus.plexus.redback.authentication.AuthenticationResult;
|
|
||||||
import org.codehaus.plexus.redback.policy.AccountLockedException;
|
|
||||||
import org.codehaus.plexus.redback.policy.MustChangePasswordException;
|
|
||||||
import org.codehaus.plexus.redback.system.SecuritySession;
|
|
||||||
import org.codehaus.plexus.redback.users.User;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* An HttpAuthenticator using an HttpSession for session storage
|
|
||||||
*
|
|
||||||
* @author Andrew Williams
|
|
||||||
* @version $Id$
|
|
||||||
* @since 1.0
|
|
||||||
*/
|
|
||||||
public abstract class SessionBasedHttpAuthenticator
|
|
||||||
extends AbstractHttpAuthenticator
|
|
||||||
{
|
|
||||||
|
|
||||||
protected Object getSessionValue( Object session, String key )
|
|
||||||
{
|
|
||||||
if ( !( session instanceof HttpSession ) )
|
|
||||||
{
|
|
||||||
throw new IllegalArgumentException( "The session for a SessionBasedAuthenticator must be a javax.servlet.http.HttpSession" );
|
|
||||||
}
|
|
||||||
|
|
||||||
return ( (HttpSession) session ).getAttribute( key );
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void setSessionValue( Object session, String key, Object value )
|
|
||||||
{
|
|
||||||
if ( !( session instanceof HttpSession ) )
|
|
||||||
{
|
|
||||||
throw new IllegalArgumentException( "The session for a SessionBasedAuthenticator must be a javax.servlet.http.HttpSession" );
|
|
||||||
}
|
|
||||||
|
|
||||||
( (HttpSession) session ).setAttribute( key, value );
|
|
||||||
}
|
|
||||||
|
|
||||||
public AuthenticationResult authenticate( AuthenticationDataSource ds, HttpSession session )
|
|
||||||
throws AuthenticationException, AccountLockedException, MustChangePasswordException
|
|
||||||
{
|
|
||||||
return super.authenticate( ds, session );
|
|
||||||
}
|
|
||||||
|
|
||||||
public User getSessionUser( HttpSession session )
|
|
||||||
{
|
|
||||||
return super.getSessionUser( session );
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isAlreadyAuthenticated( HttpSession session )
|
|
||||||
{
|
|
||||||
return super.isAlreadyAuthenticated( session );
|
|
||||||
}
|
|
||||||
|
|
||||||
public SecuritySession getSecuritySession( HttpSession session )
|
|
||||||
{
|
|
||||||
return super.getSecuritySession( session );
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setSecuritySession( SecuritySession session, HttpSession sessionObj )
|
|
||||||
{
|
|
||||||
super.setSecuritySession( session, sessionObj );
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setSessionUser( User user, HttpSession session )
|
|
||||||
{
|
|
||||||
super.setSessionUser( user, session );
|
|
||||||
}
|
|
||||||
|
|
||||||
public String storeDefaultUser( String principal, HttpSession session )
|
|
||||||
{
|
|
||||||
return super.storeDefaultUser( principal, session );
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,119 +0,0 @@
|
||||||
package org.codehaus.plexus.redback.http.authentication.basic;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Licensed to the Apache Software Foundation (ASF) under one
|
|
||||||
* or more contributor license agreements. See the NOTICE file
|
|
||||||
* distributed with this work for additional information
|
|
||||||
* regarding copyright ownership. The ASF licenses this file
|
|
||||||
* to you 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
|
||||||
import javax.servlet.http.HttpServletResponse;
|
|
||||||
import javax.servlet.http.HttpSession;
|
|
||||||
|
|
||||||
import org.apache.commons.codec.binary.Base64;
|
|
||||||
import org.codehaus.plexus.redback.authentication.AuthenticationException;
|
|
||||||
import org.codehaus.plexus.redback.authentication.AuthenticationResult;
|
|
||||||
import org.codehaus.plexus.redback.authentication.PasswordBasedAuthenticationDataSource;
|
|
||||||
import org.codehaus.plexus.redback.http.authentication.SessionBasedHttpAuthenticator;
|
|
||||||
import org.codehaus.plexus.redback.policy.AccountLockedException;
|
|
||||||
import org.codehaus.plexus.redback.policy.MustChangePasswordException;
|
|
||||||
import org.codehaus.plexus.util.StringUtils;
|
|
||||||
import org.springframework.stereotype.Service;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* HttpBasicAuthentication
|
|
||||||
*
|
|
||||||
* @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
|
|
||||||
* @author Andrew Williams
|
|
||||||
* @version $Id$
|
|
||||||
*/
|
|
||||||
@Service("httpAuthenticator#basic")
|
|
||||||
public class HttpBasicAuthentication
|
|
||||||
extends SessionBasedHttpAuthenticator
|
|
||||||
{
|
|
||||||
|
|
||||||
public String getId()
|
|
||||||
{
|
|
||||||
return HttpBasicAuthentication.class.getName();
|
|
||||||
}
|
|
||||||
|
|
||||||
public AuthenticationResult getAuthenticationResult( HttpServletRequest request, HttpServletResponse response )
|
|
||||||
throws AuthenticationException, AccountLockedException, MustChangePasswordException
|
|
||||||
{
|
|
||||||
HttpSession session = request.getSession();
|
|
||||||
|
|
||||||
if ( isAlreadyAuthenticated( session ) )
|
|
||||||
{
|
|
||||||
return getSecuritySession( session ).getAuthenticationResult();
|
|
||||||
}
|
|
||||||
|
|
||||||
PasswordBasedAuthenticationDataSource authDataSource;
|
|
||||||
String header = request.getHeader( "Authorization" );
|
|
||||||
|
|
||||||
// in tomcat this is : authorization=Basic YWRtaW46TWFuYWdlMDc=
|
|
||||||
if ( header == null )
|
|
||||||
{
|
|
||||||
header = request.getHeader("authorization");
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( ( header != null ) && header.startsWith( "Basic " ) )
|
|
||||||
{
|
|
||||||
String base64Token = header.substring( 6 );
|
|
||||||
String token = new String( Base64.decodeBase64( base64Token.getBytes() ) );
|
|
||||||
|
|
||||||
String username = "";
|
|
||||||
String password = "";
|
|
||||||
int delim = token.indexOf( ':' );
|
|
||||||
|
|
||||||
if ( delim != ( -1 ) )
|
|
||||||
{
|
|
||||||
username = token.substring( 0, delim );
|
|
||||||
password = token.substring( delim + 1 );
|
|
||||||
}
|
|
||||||
|
|
||||||
authDataSource = new PasswordBasedAuthenticationDataSource( username, password );
|
|
||||||
return super.authenticate( authDataSource, session );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return a HTTP 403 - Access Denied response.
|
|
||||||
*
|
|
||||||
* @param request the request to use.
|
|
||||||
* @param response the response to use.
|
|
||||||
* @param realmName the realm name to state.
|
|
||||||
* @param exception the exception to base the message off of.
|
|
||||||
* @throws IOException if there was a problem with the {@link HttpServletResponse#sendError(int,String)} call.
|
|
||||||
*/
|
|
||||||
public void challenge( HttpServletRequest request, HttpServletResponse response, String realmName,
|
|
||||||
AuthenticationException exception )
|
|
||||||
throws IOException
|
|
||||||
{
|
|
||||||
response.addHeader( "WWW-Authenticate", "Basic realm=\"" + realmName + "\"" );
|
|
||||||
String message = "You must provide a username and password to access this resource.";
|
|
||||||
if ( ( exception != null ) && StringUtils.isNotEmpty( exception.getMessage() ) )
|
|
||||||
{
|
|
||||||
message = exception.getMessage();
|
|
||||||
}
|
|
||||||
response.sendError( HttpServletResponse.SC_UNAUTHORIZED, message );
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,51 +0,0 @@
|
||||||
package org.codehaus.plexus.redback.http.authentication.digest;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Licensed to the Apache Software Foundation (ASF) under one
|
|
||||||
* or more contributor license agreements. See the NOTICE file
|
|
||||||
* distributed with this work for additional information
|
|
||||||
* regarding copyright ownership. The ASF licenses this file
|
|
||||||
* to you 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
import java.security.MessageDigest;
|
|
||||||
import java.security.NoSuchAlgorithmException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Digest
|
|
||||||
*
|
|
||||||
* @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
|
|
||||||
* @version $Id$
|
|
||||||
* @todo move to plexus-utils in future
|
|
||||||
*/
|
|
||||||
public class Digest
|
|
||||||
{
|
|
||||||
public static String md5Hex( String data )
|
|
||||||
{
|
|
||||||
MessageDigest digest = getDigest( "MD5" );
|
|
||||||
return Hex.encode( digest.digest( data.getBytes() ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
public static MessageDigest getDigest( String algorithm )
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
return MessageDigest.getInstance( algorithm );
|
|
||||||
}
|
|
||||||
catch ( NoSuchAlgorithmException e )
|
|
||||||
{
|
|
||||||
throw new RuntimeException( "Error initializing MessageDigest: " + e.getMessage(), e );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,52 +0,0 @@
|
||||||
package org.codehaus.plexus.redback.http.authentication.digest;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Licensed to the Apache Software Foundation (ASF) under one
|
|
||||||
* or more contributor license agreements. See the NOTICE file
|
|
||||||
* distributed with this work for additional information
|
|
||||||
* regarding copyright ownership. The ASF licenses this file
|
|
||||||
* to you 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Hex
|
|
||||||
*
|
|
||||||
* @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
|
|
||||||
* @version $Id$
|
|
||||||
* @todo should probably move this to plexus-utils or plexus-security-common
|
|
||||||
*/
|
|
||||||
public class Hex
|
|
||||||
{
|
|
||||||
private static final byte[] DIGITS = "0123456789abcdef".getBytes();
|
|
||||||
|
|
||||||
public static String encode( byte[] data )
|
|
||||||
{
|
|
||||||
int l = data.length;
|
|
||||||
|
|
||||||
byte[] raw = new byte[l * 2];
|
|
||||||
|
|
||||||
for ( int i = 0, j = 0; i < l; i++ )
|
|
||||||
{
|
|
||||||
raw[j++] = DIGITS[( 0xF0 & data[i] ) >>> 4];
|
|
||||||
raw[j++] = DIGITS[0x0F & data[i]];
|
|
||||||
}
|
|
||||||
|
|
||||||
return new String( raw );
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String encode( String raw )
|
|
||||||
{
|
|
||||||
return encode( raw.getBytes() );
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,212 +0,0 @@
|
||||||
package org.codehaus.plexus.redback.http.authentication.digest;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Licensed to the Apache Software Foundation (ASF) under one
|
|
||||||
* or more contributor license agreements. See the NOTICE file
|
|
||||||
* distributed with this work for additional information
|
|
||||||
* regarding copyright ownership. The ASF licenses this file
|
|
||||||
* to you 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
import org.apache.commons.codec.binary.Base64;
|
|
||||||
import org.codehaus.plexus.redback.authentication.AuthenticationException;
|
|
||||||
import org.codehaus.plexus.redback.authentication.AuthenticationResult;
|
|
||||||
import org.codehaus.plexus.redback.authentication.TokenBasedAuthenticationDataSource;
|
|
||||||
import org.codehaus.plexus.redback.http.authentication.HttpAuthenticationException;
|
|
||||||
import org.codehaus.plexus.redback.http.authentication.SessionBasedHttpAuthenticator;
|
|
||||||
import org.codehaus.plexus.redback.policy.AccountLockedException;
|
|
||||||
import org.codehaus.plexus.redback.policy.MustChangePasswordException;
|
|
||||||
import org.codehaus.plexus.redback.users.User;
|
|
||||||
import org.codehaus.plexus.redback.users.UserManager;
|
|
||||||
import org.codehaus.plexus.redback.users.UserNotFoundException;
|
|
||||||
import org.codehaus.plexus.util.StringUtils;
|
|
||||||
import org.springframework.stereotype.Service;
|
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
|
||||||
import javax.servlet.http.HttpServletResponse;
|
|
||||||
import javax.servlet.http.HttpSession;
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* HttpDigestAuthentication methods for working with <a href="http://www.faqs.org/rfcs/rfc2617.html">RFC 2617 HTTP Authentication</a>.
|
|
||||||
*
|
|
||||||
* @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
|
|
||||||
* @author Andrew Williams
|
|
||||||
* @version $Id$
|
|
||||||
*/
|
|
||||||
@Service( "attpAuthenticator#digest" )
|
|
||||||
public class HttpDigestAuthentication
|
|
||||||
extends SessionBasedHttpAuthenticator
|
|
||||||
{
|
|
||||||
@Resource( name = "userManager#configurable" )
|
|
||||||
private UserManager userManager;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
private int nonceLifetimeSeconds = 300;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* NOTE: Must be alphanumeric.
|
|
||||||
*/
|
|
||||||
private String digestKey = "OrycteropusAfer";
|
|
||||||
|
|
||||||
private String realm;
|
|
||||||
|
|
||||||
public String getId()
|
|
||||||
{
|
|
||||||
return HttpDigestAuthentication.class.getName();
|
|
||||||
}
|
|
||||||
|
|
||||||
public AuthenticationResult getAuthenticationResult( HttpServletRequest request, HttpServletResponse response )
|
|
||||||
throws AuthenticationException, AccountLockedException, MustChangePasswordException
|
|
||||||
{
|
|
||||||
HttpSession session = request.getSession();
|
|
||||||
|
|
||||||
if ( isAlreadyAuthenticated( session ) )
|
|
||||||
{
|
|
||||||
return getSecuritySession( session ).getAuthenticationResult();
|
|
||||||
}
|
|
||||||
|
|
||||||
TokenBasedAuthenticationDataSource authDataSource = new TokenBasedAuthenticationDataSource();
|
|
||||||
String authHeader = request.getHeader( "Authorization" );
|
|
||||||
|
|
||||||
// in tomcat this is : authorization=Basic YWRtaW46TWFuYWdlMDc=
|
|
||||||
if ( authHeader == null )
|
|
||||||
{
|
|
||||||
authHeader = request.getHeader( "authorization" );
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( ( authHeader != null ) && authHeader.startsWith( "Digest " ) )
|
|
||||||
{
|
|
||||||
String rawDigestHeader = authHeader.substring( 7 );
|
|
||||||
|
|
||||||
HttpDigestHeader digestHeader = new HttpDigestHeader();
|
|
||||||
digestHeader.parseClientHeader( rawDigestHeader, getRealm(), digestKey );
|
|
||||||
|
|
||||||
// Lookup password for presented username
|
|
||||||
User user = findUser( digestHeader.username );
|
|
||||||
authDataSource.setPrincipal( user.getPrincipal().toString() );
|
|
||||||
|
|
||||||
String serverSideHash = generateDigestHash( digestHeader, user.getPassword(), request.getMethod() );
|
|
||||||
|
|
||||||
if ( !StringUtils.equals( serverSideHash, digestHeader.response ) )
|
|
||||||
{
|
|
||||||
throw new HttpAuthenticationException( "Digest response was invalid." );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return super.authenticate( authDataSource, session );
|
|
||||||
}
|
|
||||||
|
|
||||||
public User findUser( String username )
|
|
||||||
throws HttpAuthenticationException
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
return userManager.findUser( username );
|
|
||||||
}
|
|
||||||
catch ( UserNotFoundException e )
|
|
||||||
{
|
|
||||||
String msg = "Unable to find primary user '" + username + "'.";
|
|
||||||
log.error( msg, e );
|
|
||||||
throw new HttpAuthenticationException( msg, e );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Issue HTTP Digest Authentication Challenge
|
|
||||||
*
|
|
||||||
* @param request the request to use.
|
|
||||||
* @param response the response to use.
|
|
||||||
* @param realmName the realm name to state.
|
|
||||||
* @param exception the exception to base the message off of.
|
|
||||||
* @throws IOException if there was a problem with the {@link HttpServletResponse#sendError(int, String)} call.
|
|
||||||
*/
|
|
||||||
public void challenge( HttpServletRequest request, HttpServletResponse response, String realmName,
|
|
||||||
AuthenticationException exception )
|
|
||||||
throws IOException
|
|
||||||
{
|
|
||||||
// The Challenge Header
|
|
||||||
StringBuilder authHeader = new StringBuilder();
|
|
||||||
authHeader.append( "Digest " );
|
|
||||||
// [REQUIRED] The name to appear in the dialog box to the user.
|
|
||||||
authHeader.append( "realm=\"" ).append( realmName ).append( "\"" );
|
|
||||||
// [OPTIONAL] We do not use the optional 'domain' header.
|
|
||||||
// authHeader.append( "domain=\"" ).append( domain ).append( "\"" );
|
|
||||||
// [REQUIRED] Nonce specification.
|
|
||||||
authHeader.append( ", nonce=\"" );
|
|
||||||
long timestamp = System.currentTimeMillis() + ( nonceLifetimeSeconds * 1000 );
|
|
||||||
// Not using ETag from RFC 2617 intentionally.
|
|
||||||
String hraw = String.valueOf( timestamp ) + ":" + digestKey;
|
|
||||||
String rawnonce = String.valueOf( timestamp ) + ":" + Digest.md5Hex( hraw );
|
|
||||||
authHeader.append( Base64.encodeBase64( rawnonce.getBytes() ) );
|
|
||||||
authHeader.append( "\"" );
|
|
||||||
// [REQUIRED] The RFC 2617 Quality of Protection.
|
|
||||||
// MSIE Appears to only support 'auth'
|
|
||||||
// Do not use 'opaque' here. (Your MSIE users will have issues)
|
|
||||||
authHeader.append( ", qop=\"auth\"" );
|
|
||||||
// [BROKEN] since we force the 'auth' qop we cannot use the opaque option.
|
|
||||||
// authHeader.append( ", opaque=\"").append(opaqueString).append("\"");
|
|
||||||
|
|
||||||
// [OPTIONAL] Use of the stale option is reserved for expired nonce strings.
|
|
||||||
if ( exception instanceof NonceExpirationException )
|
|
||||||
{
|
|
||||||
authHeader.append( ", stale=\"true\"" );
|
|
||||||
}
|
|
||||||
|
|
||||||
// [OPTIONAL] We do not use the optional Algorithm header.
|
|
||||||
// authHeader.append( ", algorithm=\"MD5\"");
|
|
||||||
|
|
||||||
response.addHeader( "WWW-Authenticate", authHeader.toString() );
|
|
||||||
response.sendError( HttpServletResponse.SC_UNAUTHORIZED, exception.getMessage() );
|
|
||||||
}
|
|
||||||
|
|
||||||
private String generateDigestHash( HttpDigestHeader digestHeader, String password, String httpMethod )
|
|
||||||
{
|
|
||||||
String a1 = Digest.md5Hex( digestHeader.username + ":" + realm + ":" + password );
|
|
||||||
String a2 = Digest.md5Hex( httpMethod + ":" + digestHeader.uri );
|
|
||||||
|
|
||||||
String digest;
|
|
||||||
|
|
||||||
if ( StringUtils.isEmpty( digestHeader.qop ) )
|
|
||||||
{
|
|
||||||
digest = a1 + ":" + digestHeader.nonce + ":" + a2;
|
|
||||||
}
|
|
||||||
else if ( StringUtils.equals( "auth", digestHeader.qop ) )
|
|
||||||
{
|
|
||||||
digest = a1 + ":" + digestHeader.nonce + ":" + digestHeader.nc + ":" + digestHeader.cnonce + ":"
|
|
||||||
+ digestHeader.qop + ":" + a2;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
throw new IllegalStateException(
|
|
||||||
"Http Digest Parameter [qop] with value of [" + digestHeader.qop + "] is unsupported." );
|
|
||||||
}
|
|
||||||
|
|
||||||
return Digest.md5Hex( digest );
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getRealm()
|
|
||||||
{
|
|
||||||
return realm;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setRealm( String realm )
|
|
||||||
{
|
|
||||||
this.realm = realm;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,148 +0,0 @@
|
||||||
package org.codehaus.plexus.redback.http.authentication.digest;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Licensed to the Apache Software Foundation (ASF) under one
|
|
||||||
* or more contributor license agreements. See the NOTICE file
|
|
||||||
* distributed with this work for additional information
|
|
||||||
* regarding copyright ownership. The ASF licenses this file
|
|
||||||
* to you 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
import org.apache.commons.codec.binary.Base64;
|
|
||||||
import org.codehaus.plexus.redback.http.HttpUtils;
|
|
||||||
import org.codehaus.plexus.redback.http.authentication.HttpAuthenticationException;
|
|
||||||
import org.codehaus.plexus.util.StringUtils;
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
import org.springframework.context.annotation.Scope;
|
|
||||||
import org.springframework.stereotype.Service;
|
|
||||||
|
|
||||||
import java.util.Properties;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* HttpDigestHeader
|
|
||||||
*
|
|
||||||
* @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
|
|
||||||
* @version $Id$
|
|
||||||
*/
|
|
||||||
@Service( "httpClientHeader" )
|
|
||||||
@Scope( "protype" )
|
|
||||||
class HttpDigestHeader
|
|
||||||
{
|
|
||||||
|
|
||||||
private Logger log = LoggerFactory.getLogger( getClass() );
|
|
||||||
|
|
||||||
public String username;
|
|
||||||
|
|
||||||
public String realm;
|
|
||||||
|
|
||||||
public String nonce;
|
|
||||||
|
|
||||||
public String uri;
|
|
||||||
|
|
||||||
public String response;
|
|
||||||
|
|
||||||
public String qop;
|
|
||||||
|
|
||||||
public String nc;
|
|
||||||
|
|
||||||
public String cnonce;
|
|
||||||
|
|
||||||
public void parseClientHeader( String rawHeader, String expectedRealm, String digestKey )
|
|
||||||
throws HttpAuthenticationException
|
|
||||||
{
|
|
||||||
Properties authHeaderProps = HttpUtils.complexHeaderToProperties( rawHeader, ",", "=" );
|
|
||||||
|
|
||||||
username = authHeaderProps.getProperty( "username" );
|
|
||||||
realm = authHeaderProps.getProperty( "realm" );
|
|
||||||
nonce = authHeaderProps.getProperty( "nonce" );
|
|
||||||
uri = authHeaderProps.getProperty( "uri" );
|
|
||||||
response = authHeaderProps.getProperty( "response" );
|
|
||||||
qop = authHeaderProps.getProperty( "qop" );
|
|
||||||
nc = authHeaderProps.getProperty( "nc" );
|
|
||||||
cnonce = authHeaderProps.getProperty( "cnonce" );
|
|
||||||
|
|
||||||
// [RFC 2067] Validate all required values
|
|
||||||
if ( StringUtils.isEmpty( username ) || StringUtils.isEmpty( realm ) || StringUtils.isEmpty( nonce )
|
|
||||||
|| StringUtils.isEmpty( uri ) || StringUtils.isEmpty( response ) )
|
|
||||||
{
|
|
||||||
log.debug( "Missing mandatory fields: Raw Digest Header : [{}]", rawHeader );
|
|
||||||
|
|
||||||
throw new HttpAuthenticationException( "Missing mandatory digest fields per RFC2069." );
|
|
||||||
}
|
|
||||||
|
|
||||||
// [RFC 2617] Validate realm.
|
|
||||||
if ( !StringUtils.equals( expectedRealm, realm ) )
|
|
||||||
{
|
|
||||||
log.debug( "Realm name is invalid: expected [{}] but got [{}]", expectedRealm, realm );
|
|
||||||
|
|
||||||
throw new HttpAuthenticationException( "Response realm does not match expected realm." );
|
|
||||||
}
|
|
||||||
|
|
||||||
// [RFC 2617] Validate "auth" qop
|
|
||||||
if ( StringUtils.equals( "auth", qop ) )
|
|
||||||
{
|
|
||||||
if ( StringUtils.isEmpty( nc ) || StringUtils.isEmpty( cnonce ) )
|
|
||||||
{
|
|
||||||
log.debug( "Missing mandatory qop fields: nc [{}] cnonce [{}]", nc, cnonce );
|
|
||||||
|
|
||||||
throw new HttpAuthenticationException( "Missing mandatory qop digest fields per RFC2617." );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// [RFC 2617] Validate nonce
|
|
||||||
if ( !Base64.isArrayByteBase64( nonce.getBytes() ) )
|
|
||||||
{
|
|
||||||
log.debug( "Nonce is not encoded in Base64: nonce [{}]", nonce );
|
|
||||||
|
|
||||||
throw new HttpAuthenticationException( "Response nonce is not encoded in Base64." );
|
|
||||||
}
|
|
||||||
|
|
||||||
// Decode nonce
|
|
||||||
String decodedNonce = new String( Base64.decodeBase64( nonce.getBytes() ) );
|
|
||||||
String nonceTokens[] = StringUtils.split( decodedNonce, ":" );
|
|
||||||
|
|
||||||
// Validate nonce format
|
|
||||||
if ( nonceTokens.length != 2 )
|
|
||||||
{
|
|
||||||
log.debug( "Nonce format expected [2] elements, but got [{}] instead. Decoded nonce [{}]",
|
|
||||||
nonceTokens.length, decodedNonce );
|
|
||||||
|
|
||||||
throw new HttpAuthenticationException(
|
|
||||||
"Nonce format is invalid. " + "Received an unexpected number of sub elements." );
|
|
||||||
}
|
|
||||||
|
|
||||||
// Extract nonce timestamp
|
|
||||||
long nonceTimestamp = 0;
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
nonceTimestamp = Long.parseLong( nonceTokens[0] );
|
|
||||||
}
|
|
||||||
catch ( NumberFormatException e )
|
|
||||||
{
|
|
||||||
throw new HttpAuthenticationException( "Unexpected nonce timestamp." );
|
|
||||||
}
|
|
||||||
|
|
||||||
// Extract nonce signature
|
|
||||||
String expectedSignature = Digest.md5Hex( nonceTimestamp + ":" + digestKey );
|
|
||||||
|
|
||||||
if ( !StringUtils.equals( expectedSignature, nonceTokens[1] ) )
|
|
||||||
{
|
|
||||||
log.error( "Nonce parameter has been compromised." );
|
|
||||||
|
|
||||||
throw new HttpAuthenticationException( "Nonce parameter has been compromised." );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,53 +0,0 @@
|
||||||
package org.codehaus.plexus.redback.http.authentication.digest;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Licensed to the Apache Software Foundation (ASF) under one
|
|
||||||
* or more contributor license agreements. See the NOTICE file
|
|
||||||
* distributed with this work for additional information
|
|
||||||
* regarding copyright ownership. The ASF licenses this file
|
|
||||||
* to you 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
import org.codehaus.plexus.redback.http.authentication.HttpAuthenticationException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* NonceExpirationException
|
|
||||||
*
|
|
||||||
* @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
|
|
||||||
* @version $Id$
|
|
||||||
*/
|
|
||||||
public class NonceExpirationException
|
|
||||||
extends HttpAuthenticationException
|
|
||||||
{
|
|
||||||
|
|
||||||
public NonceExpirationException()
|
|
||||||
{
|
|
||||||
super();
|
|
||||||
}
|
|
||||||
|
|
||||||
public NonceExpirationException( String message, Throwable cause )
|
|
||||||
{
|
|
||||||
super( message, cause );
|
|
||||||
}
|
|
||||||
|
|
||||||
public NonceExpirationException( String message )
|
|
||||||
{
|
|
||||||
super( message );
|
|
||||||
}
|
|
||||||
|
|
||||||
public NonceExpirationException( Throwable cause )
|
|
||||||
{
|
|
||||||
super( cause );
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,33 +0,0 @@
|
||||||
<?xml version="1.0"?>
|
|
||||||
|
|
||||||
<!--
|
|
||||||
~ Licensed to the Apache Software Foundation (ASF) under one
|
|
||||||
~ or more contributor license agreements. See the NOTICE file
|
|
||||||
~ distributed with this work for additional information
|
|
||||||
~ regarding copyright ownership. The ASF licenses this file
|
|
||||||
~ to you 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.
|
|
||||||
-->
|
|
||||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
|
||||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
|
||||||
xmlns:context="http://www.springframework.org/schema/context"
|
|
||||||
xsi:schemaLocation="http://www.springframework.org/schema/beans
|
|
||||||
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
|
|
||||||
http://www.springframework.org/schema/context
|
|
||||||
http://www.springframework.org/schema/context/spring-context-2.5.xsd"
|
|
||||||
default-lazy-init="true">
|
|
||||||
|
|
||||||
<context:annotation-config />
|
|
||||||
<context:component-scan base-package="org.codehaus.plexus.redback.http.authentication"/>
|
|
||||||
|
|
||||||
</beans>
|
|
|
@ -1,43 +0,0 @@
|
||||||
package org.codehaus.plexus.redback.http.authentication.digest;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Licensed to the Apache Software Foundation (ASF) under one
|
|
||||||
* or more contributor license agreements. See the NOTICE file
|
|
||||||
* distributed with this work for additional information
|
|
||||||
* regarding copyright ownership. The ASF licenses this file
|
|
||||||
* to you 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
import junit.framework.TestCase;
|
|
||||||
|
|
||||||
public class HexTest
|
|
||||||
extends TestCase
|
|
||||||
{
|
|
||||||
public void testEncoding()
|
|
||||||
{
|
|
||||||
String raw = "Lenore\nLenore";
|
|
||||||
String lenoreHex = "4c656e6f7265";
|
|
||||||
String expected = lenoreHex + "0a" + lenoreHex;
|
|
||||||
|
|
||||||
assertEquals( expected, Hex.encode( raw ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testTheRaven()
|
|
||||||
{
|
|
||||||
String raw = "Quoth the Raven, \"Nevermore.\"";
|
|
||||||
String expected = "51756f74682074686520526176656e2c20224e657665726d6f72652e22";
|
|
||||||
|
|
||||||
assertEquals( expected, Hex.encode( raw.getBytes() ) );
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in New Issue