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