Skip to content

Commit b4bfc05

Browse files
committed
Added tests for JASPIC register session with custom principal
1 parent 24b94df commit b4bfc05

File tree

6 files changed

+280
-19
lines changed

6 files changed

+280
-19
lines changed
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package org.javaee7.jaspic.registersession.sam;
2+
3+
import java.security.Principal;
4+
5+
/**
6+
*
7+
* @author Arjan Tijms
8+
*
9+
*/
10+
public class MyPrincipal implements Principal {
11+
12+
private final String name;
13+
14+
public MyPrincipal(String name) {
15+
this.name = name;
16+
}
17+
18+
@Override
19+
public String getName() {
20+
return name;
21+
}
22+
23+
}

jaspic/register-session/src/main/java/org/javaee7/jaspic/registersession/sam/TestServerAuthModule.java

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
import java.io.IOException;
77
import java.security.Principal;
88
import java.util.Map;
9-
import java.util.logging.Logger;
109

1110
import javax.security.auth.Subject;
1211
import javax.security.auth.callback.Callback;
@@ -22,15 +21,14 @@
2221
import javax.servlet.http.HttpServletRequest;
2322
import javax.servlet.http.HttpServletResponse;
2423

24+
2525
/**
2626
*
2727
* @author Arjan Tijms
2828
*
2929
*/
3030
public class TestServerAuthModule implements ServerAuthModule {
3131

32-
Logger logger = Logger.getLogger("blalllalala");
33-
3432
private CallbackHandler handler;
3533
private Class<?>[] supportedMessageTypes = new Class[] { HttpServletRequest.class, HttpServletResponse.class };
3634

@@ -65,7 +63,15 @@ public AuthStatus validateRequest(MessageInfo messageInfo, Subject clientSubject
6563

6664
callbacks = new Callback[] {
6765
// The name of the authenticated user
68-
new CallerPrincipalCallback(clientSubject, "test"),
66+
67+
request.getParameter("customPrincipal") == null?
68+
// Name based Callback
69+
new CallerPrincipalCallback(clientSubject, "test") :
70+
71+
// Custom principal based Callback
72+
new CallerPrincipalCallback(clientSubject, new MyPrincipal("test")),
73+
74+
6975
// the roles of the authenticated user
7076
new GroupPrincipalCallback(clientSubject, new String[] { "architect" }) };
7177

jaspic/register-session/src/main/java/org/javaee7/jaspic/registersession/servlet/ProtectedServlet.java

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,17 @@
11
package org.javaee7.jaspic.registersession.servlet;
22

33
import java.io.IOException;
4+
import java.security.Principal;
45

56
import javax.servlet.ServletException;
67
import javax.servlet.annotation.WebServlet;
78
import javax.servlet.http.HttpServlet;
89
import javax.servlet.http.HttpServletRequest;
910
import javax.servlet.http.HttpServletResponse;
1011

12+
import org.javaee7.jaspic.registersession.sam.MyPrincipal;
13+
14+
1115
/**
1216
*
1317
* @author Arjan Tijms
@@ -22,16 +26,19 @@ public class ProtectedServlet extends HttpServlet {
2226
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
2327

2428
response.getWriter().write("This is a protected servlet \n");
25-
29+
2630
String webName = null;
31+
boolean isCustomPrincipal = false;
2732
if (request.getUserPrincipal() != null) {
33+
Principal principal = request.getUserPrincipal();
34+
isCustomPrincipal = principal instanceof MyPrincipal;
2835
webName = request.getUserPrincipal().getName();
2936
}
3037

31-
response.getWriter().write("web username: " + webName + "\n");
32-
3338
boolean webHasRole = request.isUserInRole("architect");
34-
39+
40+
response.getWriter().write("isCustomPrincipal: " + isCustomPrincipal + "\n");
41+
response.getWriter().write("web username: " + webName + "\n");
3542
response.getWriter().write("web user has role \"architect\": " + webHasRole + "\n");
3643

3744
}

jaspic/register-session/src/main/java/org/javaee7/jaspic/registersession/servlet/PublicServlet.java

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,17 @@
11
package org.javaee7.jaspic.registersession.servlet;
22

33
import java.io.IOException;
4+
import java.security.Principal;
45

56
import javax.servlet.ServletException;
67
import javax.servlet.annotation.WebServlet;
78
import javax.servlet.http.HttpServlet;
89
import javax.servlet.http.HttpServletRequest;
910
import javax.servlet.http.HttpServletResponse;
1011

12+
import org.javaee7.jaspic.registersession.sam.MyPrincipal;
13+
14+
1115
/**
1216
*
1317
* @author Arjan Tijms
@@ -24,14 +28,17 @@ public void doGet(HttpServletRequest request, HttpServletResponse response) thro
2428
response.getWriter().write("This is a public servlet \n");
2529

2630
String webName = null;
31+
boolean isCustomPrincipal = false;
2732
if (request.getUserPrincipal() != null) {
28-
webName = request.getUserPrincipal().getName();
33+
Principal principal = request.getUserPrincipal();
34+
isCustomPrincipal = principal instanceof MyPrincipal;
35+
webName = principal.getName();
2936
}
30-
31-
response.getWriter().write("web username: " + webName + "\n");
32-
37+
3338
boolean webHasRole = request.isUserInRole("architect");
3439

40+
response.getWriter().write("isCustomPrincipal: " + isCustomPrincipal + "\n");
41+
response.getWriter().write("web username: " + webName + "\n");
3542
response.getWriter().write("web user has role \"architect\": " + webHasRole + "\n");
3643

3744
}
Lines changed: 187 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,187 @@
1+
package org.javaee7.jaspic.registersession;
2+
3+
import static org.junit.Assert.assertFalse;
4+
import static org.junit.Assert.assertTrue;
5+
6+
import java.io.IOException;
7+
8+
import org.javaee7.jaspic.common.ArquillianBase;
9+
import org.jboss.arquillian.container.test.api.Deployment;
10+
import org.jboss.arquillian.junit.Arquillian;
11+
import org.jboss.shrinkwrap.api.Archive;
12+
import org.junit.Test;
13+
import org.junit.runner.RunWith;
14+
import org.xml.sax.SAXException;
15+
16+
/**
17+
* Variant of the {@link RegisterSessionTest}, where a custom principal is used instead
18+
* of a container provided one. This is particularly challenging since the SAM has to
19+
* pass the principal obtained from HttpServletRequest into the CallbackHandler, which
20+
* then somehow has to recognize this as the signal to continue an authenticated session.
21+
*
22+
* @author Arjan Tijms
23+
*
24+
*/
25+
@RunWith(Arquillian.class)
26+
public class RegisterSessionCustomPrincipalTest extends ArquillianBase {
27+
28+
@Deployment(testable = false)
29+
public static Archive<?> createDeployment() {
30+
return defaultArchive();
31+
}
32+
33+
@Test
34+
public void testRemembersSession() throws IOException, SAXException {
35+
36+
// -------------------- Request 1 ---------------------------
37+
38+
// Accessing protected page without login
39+
String response = getFromServerPath("protected/servlet");
40+
41+
// Not logged-in thus should not be accessible.
42+
assertFalse(response.contains("This is a protected servlet"));
43+
44+
45+
// -------------------- Request 2 ---------------------------
46+
47+
// We access the protected page again and now login
48+
49+
response = getFromServerPath("protected/servlet?doLogin=true&customPrincipal=true");
50+
51+
// Now has to be logged-in so page is accessible
52+
assertTrue(
53+
"Could not access protected page, but should be able to. " +
54+
"Did the container remember the previously set 'unauthenticated identity'?",
55+
response.contains("This is a protected servlet")
56+
);
57+
58+
// Check principal has right name and right type and roles are available
59+
checkAuthenticatedIdentity(response);
60+
61+
62+
// -------------------- Request 3 ---------------------------
63+
64+
// JASPIC is normally stateless, but for this test the SAM uses the register session feature so now
65+
// we should be logged-in when doing a call without explicitly logging in again.
66+
67+
response = getFromServerPath("protected/servlet?continueSession=true");
68+
69+
// Logged-in thus should be accessible.
70+
assertTrue(
71+
"Could not access protected page, but should be able to. " +
72+
"Did the container not remember the authenticated identity via 'javax.servlet.http.registerSession'?",
73+
response.contains("This is a protected servlet")
74+
);
75+
76+
// Both the user name and roles/groups have to be restored
77+
78+
// *** NOTE ***: The JASPIC 1.1 spec is NOT clear about remembering roles, but spec lead Ron Monzillo clarified that
79+
// this should indeed be the case. The next JASPIC revision of the spec will have to mention this explicitly.
80+
// Intuitively it should make sense though that the authenticated identity is fully restored and not partially,
81+
// but again the spec should make this clear to avoid ambiguity.
82+
83+
checkAuthenticatedIdentity(response);
84+
85+
// -------------------- Request 4 ---------------------------
86+
87+
// The session should also be remembered for other resources, including public ones
88+
89+
response = getFromServerPath("public/servlet?continueSession=true");
90+
91+
// This test almost can't fail, but include for clarity
92+
assertTrue(response.contains("This is a public servlet"));
93+
94+
// When accessing the public page, the username and roles should be restored and be available
95+
// just as on protected pages
96+
checkAuthenticatedIdentity(response);
97+
}
98+
99+
@Test
100+
public void testJoinSessionIsOptional() throws IOException, SAXException {
101+
102+
// -------------------- Request 1 ---------------------------
103+
104+
// We access a protected page and login
105+
//
106+
107+
String response = getFromServerPath("protected/servlet?doLogin=true&customPrincipal=true");
108+
109+
// Now has to be logged-in so page is accessible
110+
assertTrue(
111+
"Could not access protected page, but should be able to. " +
112+
"Did the container remember the previously set 'unauthenticated identity'?",
113+
response.contains("This is a protected servlet")
114+
);
115+
116+
// Check principal has right name and right type and roles are available
117+
checkAuthenticatedIdentity(response);
118+
119+
120+
121+
122+
// -------------------- Request 2 ---------------------------
123+
124+
// JASPIC is normally stateless, but for this test the SAM uses the register session feature so now
125+
// we should be logged-in when doing a call without explicitly logging in again.
126+
127+
response = getFromServerPath("protected/servlet?continueSession=true");
128+
129+
// Logged-in thus should be accessible.
130+
assertTrue(
131+
"Could not access protected page, but should be able to. " +
132+
"Did the container not remember the authenticated identity via 'javax.servlet.http.registerSession'?",
133+
response.contains("This is a protected servlet")
134+
);
135+
136+
// Both the user name and roles/groups have to be restored
137+
138+
// *** NOTE ***: The JASPIC 1.1 spec is NOT clear about remembering roles, but spec lead Ron Monzillo clarified that
139+
// this should indeed be the case. The next JASPIC revision of the spec will have to mention this explicitly.
140+
// Intuitively it should make sense though that the authenticated identity is fully restored and not partially,
141+
// but again the spec should make this clear to avoid ambiguity.
142+
// Check principal has right name and right type and roles are available
143+
checkAuthenticatedIdentity(response);
144+
145+
146+
// -------------------- Request 3 ---------------------------
147+
148+
// Although the container remembers the authentication session, the SAM needs to OPT-IN to it.
149+
// If the SAM instead "does nothing", we should not have access to the protected resource anymore
150+
// even within the same HTTP session.
151+
152+
response = getFromServerPath("protected/servlet");
153+
assertFalse(response.contains("This is a protected servlet"));
154+
155+
156+
// -------------------- Request 4 ---------------------------
157+
158+
// Access to a public page is unaffected by joining or not joining the session, but if we do not join the
159+
// session we shouldn't see the user's name and roles.
160+
161+
response = getFromServerPath("public/servlet");
162+
163+
assertTrue(response.contains("This is a public servlet"));
164+
assertFalse(response.contains("web username: test"));
165+
assertFalse(response.contains("web user has role \"architect\": true"));
166+
}
167+
168+
private void checkAuthenticatedIdentity( String response) {
169+
170+
// Has to be logged-in with the right principal
171+
assertTrue(
172+
"Authenticated but username is not the expected one 'test'",
173+
response.contains("web username: test")
174+
);
175+
assertTrue(
176+
"Authentication succeeded and username is correct, but the expected role 'architect' is not present.",
177+
response.contains("web user has role \"architect\": true"));
178+
179+
assertTrue(
180+
"Authentication succeeded and username and roles are correct, but principal type is not the expected custom type.",
181+
response.contains("isCustomPrincipal: true")
182+
);
183+
}
184+
185+
186+
187+
}

0 commit comments

Comments
 (0)