Skip to content

Commit

Permalink
Custom instances of GenericPrincipal in WaffleAuthenticatorBase (#571)
Browse files Browse the repository at this point in the history
* Custom instances of GenericPrincipal in WaffleAuthenticatorBase
subclasses #561

* #571

* #571 (comment)

#571
+- replaced double space by single space

* #571

+ test case for custom principal

* #571 Custom instances of
GenericPrincipal in WaffleAuthenticatorBase #571

@Snap252 Can you add the same test case to tomcat7,8,9? Spring has now
released spring security 5 so now just wating on that piece from you to
merge this then a few rounds of testing and this will be released.
Thanks.
  • Loading branch information
Snap252 authored and hazendaz committed Dec 3, 2017
1 parent 7f7e405 commit 75f274e
Show file tree
Hide file tree
Showing 16 changed files with 227 additions and 68 deletions.
Expand Up @@ -26,6 +26,7 @@
import org.apache.catalina.LifecycleException;
import org.apache.catalina.connector.Request;
import org.apache.catalina.deploy.LoginConfig;
import org.apache.catalina.realm.GenericPrincipal;
import org.slf4j.LoggerFactory;

import waffle.util.AuthorizationHeader;
Expand Down Expand Up @@ -254,17 +255,15 @@ private boolean post(final Request request, final HttpServletResponse response)
try {
this.log.debug("successfully logged in {} ({})", username, windowsIdentity.getSidString());

final GenericWindowsPrincipal windowsPrincipal = new GenericWindowsPrincipal(windowsIdentity,
this.principalFormat, this.roleFormat);

this.log.debug("roles: {}", windowsPrincipal.getRolesString());
final GenericPrincipal genericPrincipal = createPrincipal(windowsIdentity);

this.log.debug("roles: {}", String.join(", ", genericPrincipal.getRoles()));
// create a session associated with this request if there's none
final HttpSession session = request.getSession(true);
this.log.debug("session id: {}", session == null ? "null" : session.getId());

this.register(request, response, windowsPrincipal, "FORM", windowsPrincipal.getName(), null);
this.log.info("successfully logged in user: {}", windowsPrincipal.getName());
this.register(request, response, genericPrincipal, "FORM", genericPrincipal.getName(), null);
this.log.info("successfully logged in user: {}", genericPrincipal.getName());
} finally {
windowsIdentity.dispose();
}
Expand Down
Expand Up @@ -23,6 +23,7 @@
import org.apache.catalina.LifecycleException;
import org.apache.catalina.connector.Request;
import org.apache.catalina.deploy.LoginConfig;
import org.apache.catalina.realm.GenericPrincipal;
import org.slf4j.LoggerFactory;

import waffle.util.AuthorizationHeader;
Expand Down Expand Up @@ -160,12 +161,11 @@ public boolean authenticate(final Request request, final HttpServletResponse res
try {
this.log.debug("logged in user: {} ({})", windowsIdentity.getFqn(), windowsIdentity.getSidString());

final GenericWindowsPrincipal windowsPrincipal = new GenericWindowsPrincipal(windowsIdentity,
this.principalFormat, this.roleFormat);
final GenericPrincipal genericPrincipal = createPrincipal(windowsIdentity);

this.log.debug("roles: {}", windowsPrincipal.getRolesString());
this.log.debug("roles: {}", String.join(", ", genericPrincipal.getRoles()));

principal = windowsPrincipal;
principal = genericPrincipal;

// create a session associated with this request if there's none
final HttpSession session = request.getSession(true);
Expand Down
Expand Up @@ -23,6 +23,7 @@

import org.apache.catalina.authenticator.AuthenticatorBase;
import org.apache.catalina.connector.Request;
import org.apache.catalina.realm.GenericPrincipal;
import org.slf4j.Logger;

import waffle.windows.auth.IWindowsAuthProvider;
Expand Down Expand Up @@ -243,13 +244,22 @@ protected Principal doLogin(final Request request, final String username, final
}
try {
this.log.debug("successfully logged in {} ({})", username, windowsIdentity.getSidString());
final GenericWindowsPrincipal windowsPrincipal = new GenericWindowsPrincipal(windowsIdentity,
this.principalFormat, this.roleFormat);
this.log.debug("roles: {}", windowsPrincipal.getRolesString());
return windowsPrincipal;
final GenericPrincipal genericPrincipal = createPrincipal(windowsIdentity);
this.log.debug("roles: {}", String.join(", ", genericPrincipal.getRoles()));
return genericPrincipal;
} finally {
windowsIdentity.dispose();
}
}

/**
* This method will create an instance of a IWindowsIdentity based GenericPrincipal.
* It is used for creating custom implementation within subclasses.
* @param windowsIdentity the windows identity to initialize the principal
* @return the Generic Principal
*/
protected GenericPrincipal createPrincipal(final IWindowsIdentity windowsIdentity) {
return new GenericWindowsPrincipal(windowsIdentity, this.principalFormat, this.roleFormat);
}

}
Expand Up @@ -14,7 +14,9 @@
import com.sun.jna.platform.win32.Sspi;
import com.sun.jna.platform.win32.Sspi.SecBufferDesc;

import java.io.IOException;
import java.util.Base64;
import java.util.Collections;

import javax.servlet.ServletException;

Expand All @@ -25,6 +27,7 @@
import org.apache.catalina.Engine;
import org.apache.catalina.LifecycleException;
import org.apache.catalina.deploy.LoginConfig;
import org.apache.catalina.realm.GenericPrincipal;
import org.assertj.core.api.Assertions;
import org.junit.After;
import org.junit.Assert;
Expand Down Expand Up @@ -364,4 +367,33 @@ public void testSecurityCheckQueryString() {
final SimpleHttpResponse response = new SimpleHttpResponse();
Assert.assertTrue(this.authenticator.authenticate(request, response, loginConfig));
}

@Test
public void testCustomPrincipal() throws LifecycleException, IOException {
final GenericPrincipal genericPrincipal = new GenericPrincipal("my-principal", "my-password", Collections.emptyList());
final MixedAuthenticator customAuthenticator = new MixedAuthenticator() {
@Override
protected GenericPrincipal createPrincipal(IWindowsIdentity windowsIdentity) {
return genericPrincipal;
}
};
try {
customAuthenticator.setContainer(this.context);
customAuthenticator.setAlwaysUseSession(true);
customAuthenticator.start();

customAuthenticator.setAuth(new MockWindowsAuthProvider());
final SimpleHttpRequest request = new SimpleHttpRequest();
request.addParameter("j_security_check", "");
request.addParameter("j_username", WindowsAccountImpl.getCurrentUsername());
request.addParameter("j_password", "");
final SimpleHttpResponse response = new SimpleHttpResponse();
Assert.assertTrue(customAuthenticator.authenticate(request, response));

Assert.assertEquals(genericPrincipal, request.getUserPrincipal());
} finally {
customAuthenticator.stop();
}

}
}
Expand Up @@ -25,6 +25,7 @@

import org.apache.catalina.LifecycleException;
import org.apache.catalina.connector.Request;
import org.apache.catalina.realm.GenericPrincipal;
import org.apache.tomcat.util.descriptor.web.LoginConfig;
import org.slf4j.LoggerFactory;

Expand Down Expand Up @@ -255,17 +256,15 @@ private boolean post(final Request request, final HttpServletResponse response)
try {
this.log.debug("successfully logged in {} ({})", username, windowsIdentity.getSidString());

final GenericWindowsPrincipal windowsPrincipal = new GenericWindowsPrincipal(windowsIdentity,
this.principalFormat, this.roleFormat);

this.log.debug("roles: {}", windowsPrincipal.getRolesString());
final GenericPrincipal genericPrincipal = createPrincipal(windowsIdentity);

this.log.debug("roles: {}", String.join(", ", genericPrincipal.getRoles()));
// create a session associated with this request if there's none
final HttpSession session = request.getSession(true);
this.log.debug("session id: {}", session == null ? "null" : session.getId());

this.register(request, response, windowsPrincipal, "FORM", windowsPrincipal.getName(), null);
this.log.info("successfully logged in user: {}", windowsPrincipal.getName());
this.register(request, response, genericPrincipal, "FORM", genericPrincipal.getName(), null);
this.log.info("successfully logged in user: {}", genericPrincipal.getName());
} finally {
windowsIdentity.dispose();
}
Expand Down
Expand Up @@ -22,6 +22,7 @@

import org.apache.catalina.LifecycleException;
import org.apache.catalina.connector.Request;
import org.apache.catalina.realm.GenericPrincipal;
import org.slf4j.LoggerFactory;

import waffle.util.AuthorizationHeader;
Expand Down Expand Up @@ -158,12 +159,11 @@ public boolean authenticate(final Request request, final HttpServletResponse res
try {
this.log.debug("logged in user: {} ({})", windowsIdentity.getFqn(), windowsIdentity.getSidString());

final GenericWindowsPrincipal windowsPrincipal = new GenericWindowsPrincipal(windowsIdentity,
this.principalFormat, this.roleFormat);
final GenericPrincipal genericPrincipal = createPrincipal(windowsIdentity);

this.log.debug("roles: {}", windowsPrincipal.getRolesString());
this.log.debug("roles: {}", String.join(", ", genericPrincipal.getRoles()));

principal = windowsPrincipal;
principal = genericPrincipal;

// create a session associated with this request if there's none
final HttpSession session = request.getSession(true);
Expand Down
Expand Up @@ -23,6 +23,7 @@

import org.apache.catalina.authenticator.AuthenticatorBase;
import org.apache.catalina.connector.Request;
import org.apache.catalina.realm.GenericPrincipal;
import org.slf4j.Logger;

import waffle.windows.auth.IWindowsAuthProvider;
Expand Down Expand Up @@ -242,13 +243,22 @@ protected Principal doLogin(final Request request, final String username, final
}
try {
this.log.debug("successfully logged in {} ({})", username, windowsIdentity.getSidString());
final GenericWindowsPrincipal windowsPrincipal = new GenericWindowsPrincipal(windowsIdentity,
this.principalFormat, this.roleFormat);
this.log.debug("roles: {}", windowsPrincipal.getRolesString());
return windowsPrincipal;
final GenericPrincipal genericPrincipal = createPrincipal(windowsIdentity);
this.log.debug("roles: {}", String.join(", ", genericPrincipal.getRoles()));
return genericPrincipal;
} finally {
windowsIdentity.dispose();
}
}

/**
* This method will create an instance of a IWindowsIdentity based GenericPrincipal.
* It is used for creating custom implementation within subclasses.
* @param windowsIdentity the windows identity to initialize the principal
* @return the Generic Principal
*/
protected GenericPrincipal createPrincipal(final IWindowsIdentity windowsIdentity) {
return new GenericWindowsPrincipal(windowsIdentity, this.principalFormat, this.roleFormat);
}

}
Expand Up @@ -15,6 +15,7 @@
import com.sun.jna.platform.win32.Sspi.SecBufferDesc;

import java.util.Base64;
import java.util.Collections;

import javax.servlet.ServletException;

Expand All @@ -24,6 +25,7 @@
import org.apache.catalina.Context;
import org.apache.catalina.Engine;
import org.apache.catalina.LifecycleException;
import org.apache.catalina.realm.GenericPrincipal;
import org.assertj.core.api.Assertions;
import org.junit.After;
import org.junit.Assert;
Expand Down Expand Up @@ -349,4 +351,33 @@ public void testSecurityCheckQueryString() {
final SimpleHttpResponse response = new SimpleHttpResponse();
Assert.assertTrue(this.authenticator.authenticate(request, response));
}

@Test
public void testCustomPrincipal() throws LifecycleException {
final GenericPrincipal genericPrincipal = new GenericPrincipal("my-principal", "my-password", Collections.emptyList());
final MixedAuthenticator customAuthenticator = new MixedAuthenticator() {
@Override
protected GenericPrincipal createPrincipal(IWindowsIdentity windowsIdentity) {
return genericPrincipal;
}
};
try {
customAuthenticator.setContainer(this.context);
customAuthenticator.setAlwaysUseSession(true);
customAuthenticator.start();

customAuthenticator.setAuth(new MockWindowsAuthProvider());
final SimpleHttpRequest request = new SimpleHttpRequest();
request.addParameter("j_security_check", "");
request.addParameter("j_username", WindowsAccountImpl.getCurrentUsername());
request.addParameter("j_password", "");
final SimpleHttpResponse response = new SimpleHttpResponse();
Assert.assertTrue(customAuthenticator.authenticate(request, response));

Assert.assertEquals(genericPrincipal, request.getUserPrincipal());
} finally {
customAuthenticator.stop();
}

}
}
Expand Up @@ -25,6 +25,7 @@

import org.apache.catalina.LifecycleException;
import org.apache.catalina.connector.Request;
import org.apache.catalina.realm.GenericPrincipal;
import org.apache.tomcat.util.descriptor.web.LoginConfig;
import org.slf4j.LoggerFactory;

Expand Down Expand Up @@ -202,17 +203,16 @@ private boolean negotiate(final Request request, final HttpServletResponse respo

this.log.debug("logged in user: {} ({})", windowsIdentity.getFqn(), windowsIdentity.getSidString());

final GenericWindowsPrincipal windowsPrincipal = new GenericWindowsPrincipal(windowsIdentity,
this.principalFormat, this.roleFormat);
final GenericPrincipal genericPrincipal = createPrincipal(windowsIdentity);

this.log.debug("roles: {}", windowsPrincipal.getRolesString());
this.log.debug("roles: {}", String.join(", ", genericPrincipal.getRoles()));

// create a session associated with this request if there's none
final HttpSession session = request.getSession(true);
this.log.debug("session id: {}", session == null ? "null" : session.getId());

this.register(request, response, windowsPrincipal, securityPackage, windowsPrincipal.getName(), null);
this.log.info("successfully logged in user: {}", windowsPrincipal.getName());
this.register(request, response, genericPrincipal, securityPackage, genericPrincipal.getName(), null);
this.log.info("successfully logged in user: {}", genericPrincipal.getName());

} finally {
windowsIdentity.dispose();
Expand Down Expand Up @@ -255,17 +255,15 @@ private boolean post(final Request request, final HttpServletResponse response)
try {
this.log.debug("successfully logged in {} ({})", username, windowsIdentity.getSidString());

final GenericWindowsPrincipal windowsPrincipal = new GenericWindowsPrincipal(windowsIdentity,
this.principalFormat, this.roleFormat);

this.log.debug("roles: {}", windowsPrincipal.getRolesString());
final GenericPrincipal genericPrincipal = createPrincipal(windowsIdentity);

this.log.debug("roles: {}", String.join(", ", genericPrincipal.getRoles()));
// create a session associated with this request if there's none
final HttpSession session = request.getSession(true);
this.log.debug("session id: {}", session == null ? "null" : session.getId());

this.register(request, response, windowsPrincipal, "FORM", windowsPrincipal.getName(), null);
this.log.info("successfully logged in user: {}", windowsPrincipal.getName());
this.register(request, response, genericPrincipal, "FORM", genericPrincipal.getName(), null);
this.log.info("successfully logged in user: {}", genericPrincipal.getName());
} finally {
windowsIdentity.dispose();
}
Expand Down
Expand Up @@ -11,8 +11,6 @@
*/
package waffle.apache;

import com.sun.jna.platform.win32.Win32Exception;

import java.io.IOException;
import java.security.Principal;
import java.util.Base64;
Expand All @@ -22,8 +20,11 @@

import org.apache.catalina.LifecycleException;
import org.apache.catalina.connector.Request;
import org.apache.catalina.realm.GenericPrincipal;
import org.slf4j.LoggerFactory;

import com.sun.jna.platform.win32.Win32Exception;

import waffle.util.AuthorizationHeader;
import waffle.util.NtlmServletRequest;
import waffle.windows.auth.IWindowsIdentity;
Expand Down Expand Up @@ -158,12 +159,11 @@ public boolean authenticate(final Request request, final HttpServletResponse res
try {
this.log.debug("logged in user: {} ({})", windowsIdentity.getFqn(), windowsIdentity.getSidString());

final GenericWindowsPrincipal windowsPrincipal = new GenericWindowsPrincipal(windowsIdentity,
this.principalFormat, this.roleFormat);
final GenericPrincipal genericPrincipal = createPrincipal(windowsIdentity);

this.log.debug("roles: {}", windowsPrincipal.getRolesString());
this.log.debug("roles: {}", String.join(", ", genericPrincipal.getRoles()));

principal = windowsPrincipal;
principal = genericPrincipal;

// create a session associated with this request if there's none
final HttpSession session = request.getSession(true);
Expand Down

0 comments on commit 75f274e

Please sign in to comment.