Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

#96 Add protocols parameter on Tomcat valves #97

Closed
wants to merge 7 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@

Features
--------
* [#97](https://github.com/dblock/waffle/pull/96): Added protocols parameter on Tomcat valves - [@hasalex](https://github.com/hasalex).
* Attribut protocols on the valve in order to limit the authentication to one or some protocols
* [#93](https://github.com/dblock/waffle/pull/93): Updated Documentation - [@hazendaz](https://github.com/hazendaz).
* First cut at updating documentation to reflect maven.
* [#92](https://github.com/dblock/waffle/pull/92): Pom Corrections - [@hazendaz](https://github.com/hazendaz).
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,7 @@ The following options are supported by the Valve.
* principalFormat: Specifies the name format for the principal.
* roleFormat: Specifies the name format for the role.
* allowGuestLogin: Allow guest login. When true and the system's Guest account is enabled, any invalid login succeeds as Guest. Note that while the default value of allowGuestLogin is true, it is recommended that you disable the system's Guest account to disallow Guest login. This option is provided for systems where you don't have administrative privileges.
* protocols: authentication protocol(s), comma separated, default is "Negotiate,NTLM"

The following principal/group formats are supported.

Expand Down
1 change: 1 addition & 0 deletions Docs/tomcat/TomcatSingleSignOnValve.md
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ The following options are supported by the Valve.
* principalFormat: Specifies the name format for the principal.
* roleFormat: Specifies the name format for the role.
* allowGuestLogin Allow guest login. When true and the system's Guest account is enabled, any invalid login succeeds as Guest.
* protocols: authentication protocol(s), comma separated, default is "Negotiate,NTLM"

Note: While the default value of `allowGuestLogin` is true, it is recommended that you disable the system's "Guest" account to disallow Guest login. This option is provided for systems where you don't have administrative privileges.

Expand Down
2 changes: 1 addition & 1 deletion Source/JNA/waffle-demo-parent/waffle-filter/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<groupId>com.github.dblock.waffle</groupId>
<artifactId>waffle-demo-parent</artifactId>
<version>1.7-SNAPSHOT</version>
<relativePath>../waffle-demo-parent</relativePath>
<relativePath>..</relativePath>
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because relative path of waffle-demo-parent is just the parent directory. And build fails with the ./waffle-demo-parent relativePath.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch! This is a pretty good indication that some refactoring is still needed to bring this into a better maven structure. I'll look at addressing that soon. The layout now is a little misleading especially around the demo. Waffle-pom suffers the same design flaw but was setup properly.

</parent>
<artifactId>waffle-filter-demo</artifactId>
<packaging>war</packaging>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<?xml version='1.0' encoding='utf-8'?>
<Context>
<Valve className="waffle.apache.MixedAuthenticator" principalFormat="fqn" roleFormat="both" allowGuestLogin="false" />
<Valve className="waffle.apache.MixedAuthenticator" principalFormat="fqn" roleFormat="both" allowGuestLogin="false" protocols="Negotiate,NTLM" />
<Realm className="waffle.apache.WindowsRealm" />
</Context>
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<?xml version='1.0' encoding='utf-8'?>
<Context>
<Valve className="waffle.apache.NegotiateAuthenticator" principalFormat="fqn" roleFormat="both" />
<Valve className="waffle.apache.NegotiateAuthenticator" principalFormat="fqn" roleFormat="both" protocols="Negotiate,NTLM" />
<Realm className="waffle.apache.WindowsRealm" />
</Context>
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
package waffle.apache;

import java.io.IOException;
import java.util.HashSet;
import java.util.Set;

import javax.servlet.http.HttpServletResponse;

Expand All @@ -25,15 +27,20 @@
import waffle.windows.auth.PrincipalFormat;
import waffle.windows.auth.impl.WindowsAuthProviderImpl;

import static java.util.Arrays.asList;

/**
* @author dblock[at]dblock[dot]org
*/
abstract class WaffleAuthenticatorBase extends AuthenticatorBase {
private static final Set<String> SUPPORTED_PROTOCOLS = new HashSet<String>(asList("Negotiate", "NTLM"));

protected String _info = null;
protected Logger _log = null;
protected PrincipalFormat _principalFormat = PrincipalFormat.fqn;
protected PrincipalFormat _roleFormat = PrincipalFormat.fqn;
protected boolean _allowGuestLogin = true;
protected Set<String> _protocols = SUPPORTED_PROTOCOLS;

protected IWindowsAuthProvider _auth = new WindowsAuthProviderImpl();

Expand Down Expand Up @@ -121,6 +128,30 @@ public void setAllowGuestLogin(boolean value) {
_allowGuestLogin = value;
}

/**
* Set the authentication protocols. Default is "Negotiate, NTLM".
*
* @param protocols
* Authentication protocols
*/
public void setProtocols(String protocols) {
_protocols = new HashSet<String>();
String[] protocolNames = protocols.split(",");
for (String protocolName : protocolNames) {
protocolName = protocolName.trim();
if (!protocolName.isEmpty()) {
_log.debug("init protocol: " + protocolName);
if (SUPPORTED_PROTOCOLS.contains(protocolName)) {
_protocols.add(protocolName);
} else {
_log.error("unsupported protocol: " + protocolName);
throw new RuntimeException("Unsupported protocol: "
+ protocolName);
}
}
}
}

/**
* Send a 401 Unauthorized along with protocol authentication headers.
*
Expand All @@ -129,8 +160,9 @@ public void setAllowGuestLogin(boolean value) {
*/
protected void sendUnauthorized(Response response) {
try {
response.addHeader("WWW-Authenticate", "Negotiate");
response.addHeader("WWW-Authenticate", "NTLM");
for (String protocol : _protocols) {
response.addHeader("WWW-Authenticate", protocol);
}
response.setHeader("Connection", "close");
response.sendError(HttpServletResponse.SC_UNAUTHORIZED);
response.flushBuffer();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
package waffle.apache;

import org.apache.catalina.connector.Request;
import org.apache.catalina.connector.Response;
import org.apache.catalina.deploy.LoginConfig;
import org.junit.Before;
import org.junit.Test;
import org.slf4j.LoggerFactory;

import java.io.IOException;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;

public class WaffleAuthenticatorBaseTest {

WaffleAuthenticatorBase waffleAuthenticatorBase;

@Before
public void init() {
waffleAuthenticatorBase = new WaffleAuthenticatorBase() {
{
_log = LoggerFactory.getLogger(WaffleAuthenticatorBaseTest.class);
}
@Override
protected boolean authenticate(Request request, Response response, LoginConfig loginConfig) throws IOException {
return false;
}
};
}

@Test
public void should_accept_NTLM_protocol() throws Exception {
waffleAuthenticatorBase.setProtocols(" NTLM ");

assertEquals("One protocol added", 1, waffleAuthenticatorBase._protocols.size());
assertEquals("NTLM", waffleAuthenticatorBase._protocols.iterator().next());
}

@Test
public void should_accept_Negotiate_protocol() throws Exception {
waffleAuthenticatorBase.setProtocols(" Negotiate ");

assertEquals("One protocol added", 1, waffleAuthenticatorBase._protocols.size());
assertEquals("Negotiate", waffleAuthenticatorBase._protocols.iterator().next());
}

@Test
public void should_accept_both_protocols() throws Exception {
waffleAuthenticatorBase.setProtocols(" NTLM , , Negotiate ");

assertEquals("Two protocols added", 2, waffleAuthenticatorBase._protocols.size());
assertTrue("NTLM has been added", waffleAuthenticatorBase._protocols.contains("NTLM"));
assertTrue("Negotiate has been added", waffleAuthenticatorBase._protocols.contains("Negotiate"));
}

@Test(expected = RuntimeException.class)
public void should_refuse_other_protocol() throws Exception {
waffleAuthenticatorBase.setProtocols(" NTLM , OTHER, Negotiate ");

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
package waffle.apache;

import java.io.IOException;
import java.util.HashSet;
import java.util.Set;

import javax.servlet.http.HttpServletResponse;

Expand All @@ -25,15 +27,20 @@
import waffle.windows.auth.PrincipalFormat;
import waffle.windows.auth.impl.WindowsAuthProviderImpl;

import static java.util.Arrays.asList;

/**
* @author dblock[at]dblock[dot]org
*/
abstract class WaffleAuthenticatorBase extends AuthenticatorBase {
private static final Set<String> SUPPORTED_PROTOCOLS = new HashSet<String>(asList("Negotiate", "NTLM"));

protected String _info = null;
protected Logger _log = null;
protected PrincipalFormat _principalFormat = PrincipalFormat.fqn;
protected PrincipalFormat _roleFormat = PrincipalFormat.fqn;
protected boolean _allowGuestLogin = true;
protected Set<String> _protocols = SUPPORTED_PROTOCOLS;

protected IWindowsAuthProvider _auth = new WindowsAuthProviderImpl();

Expand Down Expand Up @@ -121,6 +128,30 @@ public void setAllowGuestLogin(boolean value) {
_allowGuestLogin = value;
}

/**
* Set the authentication protocols. Default is "Negotiate, NTLM".
*
* @param protocols
* Authentication protocols
*/
public void setProtocols(String protocols) {
_protocols = new HashSet<String>();
String[] protocolNames = protocols.split(",");
for (String protocolName : protocolNames) {
protocolName = protocolName.trim();
if (!protocolName.isEmpty()) {
_log.debug("init protocol: " + protocolName);
if (SUPPORTED_PROTOCOLS.contains(protocolName)) {
_protocols.add(protocolName);
} else {
_log.error("unsupported protocol: " + protocolName);
throw new RuntimeException("Unsupported protocol: "
+ protocolName);
}
}
}
}

/**
* Send a 401 Unauthorized along with protocol authentication headers.
*
Expand All @@ -129,8 +160,9 @@ public void setAllowGuestLogin(boolean value) {
*/
protected void sendUnauthorized(Response response) {
try {
response.addHeader("WWW-Authenticate", "Negotiate");
response.addHeader("WWW-Authenticate", "NTLM");
for (String protocol : _protocols) {
response.addHeader("WWW-Authenticate", protocol);
}
response.setHeader("Connection", "close");
response.sendError(HttpServletResponse.SC_UNAUTHORIZED);
response.flushBuffer();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
package waffle.apache;

import org.apache.catalina.connector.Request;
import org.apache.catalina.connector.Response;
import org.apache.catalina.deploy.LoginConfig;
import org.junit.Before;
import org.junit.Test;
import org.slf4j.LoggerFactory;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;

public class WaffleAuthenticatorBaseTest {

WaffleAuthenticatorBase waffleAuthenticatorBase;

@Before
public void init() {
waffleAuthenticatorBase = new WaffleAuthenticatorBase() {
{
_log = LoggerFactory.getLogger(WaffleAuthenticatorBaseTest.class);
}
@Override
protected boolean authenticate(Request request, Response response, LoginConfig loginConfig) throws IOException {
return false;
}
};
}

@Test
public void should_accept_NTLM_protocol() throws Exception {
waffleAuthenticatorBase.setProtocols(" NTLM ");

assertEquals("One protocol added", 1, waffleAuthenticatorBase._protocols.size());
assertEquals("NTLM", waffleAuthenticatorBase._protocols.iterator().next());
}

@Test
public void should_accept_Negotiate_protocol() throws Exception {
waffleAuthenticatorBase.setProtocols(" Negotiate ");

assertEquals("One protocol added", 1, waffleAuthenticatorBase._protocols.size());
assertEquals("Negotiate", waffleAuthenticatorBase._protocols.iterator().next());
}

@Test
public void should_accept_both_protocols() throws Exception {
waffleAuthenticatorBase.setProtocols(" NTLM , , Negotiate ");

assertEquals("Two protocols added", 2, waffleAuthenticatorBase._protocols.size());
assertTrue("NTLM has been added", waffleAuthenticatorBase._protocols.contains("NTLM"));
assertTrue("Negotiate has been added", waffleAuthenticatorBase._protocols.contains("Negotiate"));
}

@Test(expected = RuntimeException.class)
public void should_refuse_other_protocol() throws Exception {
waffleAuthenticatorBase.setProtocols(" NTLM , OTHER, Negotiate ");

}
}
Loading