1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.syncope.wa.starter;
20
21 import static org.junit.jupiter.api.Assertions.assertEquals;
22 import static org.junit.jupiter.api.Assertions.assertNotNull;
23 import static org.junit.jupiter.api.Assertions.assertTrue;
24
25 import java.util.Collection;
26 import java.util.List;
27 import java.util.Map;
28 import java.util.Set;
29 import org.apache.syncope.common.lib.auth.OIDCAuthModuleConf;
30 import org.apache.syncope.common.lib.policy.AccessPolicyTO;
31 import org.apache.syncope.common.lib.policy.AttrReleasePolicyTO;
32 import org.apache.syncope.common.lib.policy.AuthPolicyTO;
33 import org.apache.syncope.common.lib.policy.DefaultAccessPolicyConf;
34 import org.apache.syncope.common.lib.policy.DefaultAttrReleasePolicyConf;
35 import org.apache.syncope.common.lib.policy.DefaultAuthPolicyConf;
36 import org.apache.syncope.common.lib.policy.DefaultTicketExpirationPolicyConf;
37 import org.apache.syncope.common.lib.policy.TicketExpirationPolicyTO;
38 import org.apache.syncope.common.lib.to.AuthModuleTO;
39 import org.apache.syncope.common.lib.to.OIDCRPClientAppTO;
40 import org.apache.syncope.common.lib.to.SAML2SPClientAppTO;
41 import org.apache.syncope.common.lib.types.LogoutType;
42 import org.apache.syncope.common.lib.types.OIDCGrantType;
43 import org.apache.syncope.common.lib.types.OIDCResponseType;
44 import org.apache.syncope.common.lib.types.OIDCSubjectType;
45 import org.apache.syncope.common.lib.types.SAML2SPNameId;
46 import org.apache.syncope.common.lib.wa.WAClientApp;
47 import org.apache.syncope.common.rest.api.service.AuthModuleService;
48 import org.apache.syncope.common.rest.api.service.wa.WAClientAppService;
49 import org.apache.syncope.wa.bootstrap.WARestClient;
50 import org.apereo.cas.authentication.AuthenticationEventExecutionPlan;
51 import org.apereo.cas.services.AnyAuthenticationHandlerRegisteredServiceAuthenticationPolicyCriteria;
52 import org.apereo.cas.services.ChainingAttributeReleasePolicy;
53 import org.apereo.cas.services.DenyAllAttributeReleasePolicy;
54 import org.apereo.cas.services.OidcRegisteredService;
55 import org.apereo.cas.services.RegisteredService;
56 import org.apereo.cas.services.RegisteredServiceAccessStrategy;
57 import org.apereo.cas.services.RegisteredServiceDelegatedAuthenticationPolicy;
58 import org.apereo.cas.services.RegisteredServiceLogoutType;
59 import org.apereo.cas.services.ServicesManager;
60 import org.apereo.cas.support.saml.services.SamlRegisteredService;
61 import org.apereo.cas.util.RandomUtils;
62 import org.junit.jupiter.api.Test;
63 import org.springframework.beans.factory.ObjectProvider;
64 import org.springframework.beans.factory.annotation.Autowired;
65 import org.springframework.cloud.context.refresh.ContextRefresher;
66
67 public class WAServiceRegistryTest extends AbstractTest {
68
69 private static OIDCRPClientAppTO buildOIDCRP() {
70 OIDCRPClientAppTO oidcrpTO = new OIDCRPClientAppTO();
71 oidcrpTO.setName("ExampleRP_" + getUUIDString());
72 oidcrpTO.setClientAppId(RandomUtils.nextLong());
73 oidcrpTO.setDescription("Example OIDC RP application");
74 oidcrpTO.setClientId("clientId_" + getUUIDString());
75 oidcrpTO.setClientSecret("secret");
76 oidcrpTO.getRedirectUris().addAll(List.of("uri1", "uri2"));
77 oidcrpTO.setSubjectType(OIDCSubjectType.PUBLIC);
78 oidcrpTO.getSupportedGrantTypes().add(OIDCGrantType.password);
79 oidcrpTO.getSupportedResponseTypes().add(OIDCResponseType.CODE);
80 oidcrpTO.setLogoutType(LogoutType.BACK_CHANNEL);
81
82 return oidcrpTO;
83 }
84
85 private static SAML2SPClientAppTO buildSAML2SP() {
86 SAML2SPClientAppTO saml2spto = new SAML2SPClientAppTO();
87 saml2spto.setName("ExampleSAML2SP_" + getUUIDString());
88 saml2spto.setClientAppId(RandomUtils.nextLong());
89 saml2spto.setDescription("Example SAML 2.0 service provider");
90 saml2spto.setEntityId("SAML2SPEntityId_" + getUUIDString());
91 saml2spto.setMetadataLocation("file:./test.xml");
92 saml2spto.setRequiredNameIdFormat(SAML2SPNameId.EMAIL_ADDRESS);
93 saml2spto.setEncryptionOptional(true);
94 saml2spto.setEncryptAssertions(true);
95 saml2spto.setLogoutType(LogoutType.BACK_CHANNEL);
96 return saml2spto;
97 }
98
99 private static void addPolicies(
100 final WAClientApp waClientApp,
101 final boolean withAttrReleasePolicy) {
102
103 DefaultAuthPolicyConf authPolicyConf = new DefaultAuthPolicyConf();
104 authPolicyConf.setTryAll(true);
105 authPolicyConf.getAuthModules().add("TestAuthModule");
106 AuthPolicyTO authPolicy = new AuthPolicyTO();
107 authPolicy.setConf(authPolicyConf);
108
109 waClientApp.setAuthPolicy(authPolicy);
110
111 AuthModuleTO authModule = new AuthModuleTO();
112 authModule.setKey("TestAuthModule");
113 waClientApp.getAuthModules().add(authModule);
114
115 AccessPolicyTO accessPolicy = new AccessPolicyTO();
116 DefaultAccessPolicyConf accessPolicyConf = new DefaultAccessPolicyConf();
117 accessPolicyConf.setEnabled(true);
118 accessPolicyConf.getRequiredAttrs().put("cn", "admin,Admin,TheAdmin");
119 accessPolicy.setConf(accessPolicyConf);
120 waClientApp.setAccessPolicy(accessPolicy);
121
122 if (withAttrReleasePolicy) {
123 DefaultAttrReleasePolicyConf attrReleasePolicyConf = new DefaultAttrReleasePolicyConf();
124 attrReleasePolicyConf.getAllowedAttrs().add("cn");
125 attrReleasePolicyConf.getPrincipalAttrRepoConf().getAttrRepos().add("TestAttrRepo");
126 attrReleasePolicyConf.getReleaseAttrs().putAll(Map.of("uid", "username", "cn", "fullname"));
127
128 AttrReleasePolicyTO attrReleasePolicy = new AttrReleasePolicyTO();
129 attrReleasePolicy.setConf(attrReleasePolicyConf);
130 waClientApp.setAttrReleasePolicy(attrReleasePolicy);
131 }
132
133 TicketExpirationPolicyTO ticketExpirationPolicy = new TicketExpirationPolicyTO();
134 DefaultTicketExpirationPolicyConf ticketExpirationPolicyConf = new DefaultTicketExpirationPolicyConf();
135 DefaultTicketExpirationPolicyConf.TGTConf tgtConf = new DefaultTicketExpirationPolicyConf.TGTConf();
136 tgtConf.setMaxTimeToLiveInSeconds(110);
137 ticketExpirationPolicyConf.setTgtConf(tgtConf);
138 ticketExpirationPolicy.setConf(ticketExpirationPolicyConf);
139 waClientApp.setTicketExpirationPolicy(ticketExpirationPolicy);
140 }
141
142 @Autowired
143 private WARestClient waRestClient;
144
145 @Autowired
146 private ServicesManager servicesManager;
147
148 @Autowired
149 private ObjectProvider<AuthenticationEventExecutionPlan> authenticationEventExecutionPlan;
150
151 @Autowired
152 private ContextRefresher contextRefresher;
153
154 @Test
155 public void addClientApp() {
156
157 SyncopeCoreTestingServer.CLIENT_APPS.clear();
158
159 WAClientAppService service = waRestClient.getService(WAClientAppService.class);
160 assertTrue(service.list().isEmpty());
161
162
163 WAClientApp waClientApp = new WAClientApp();
164 waClientApp.setClientAppTO(buildOIDCRP());
165 Long clientAppId = waClientApp.getClientAppTO().getClientAppId();
166 addPolicies(waClientApp, false);
167
168 SyncopeCoreTestingServer.CLIENT_APPS.add(waClientApp);
169 List<WAClientApp> apps = service.list();
170 assertEquals(1, apps.size());
171
172 assertNotNull(servicesManager.findServiceBy(clientAppId));
173
174
175 Collection<RegisteredService> load = servicesManager.load();
176 assertEquals(3, load.size());
177
178
179 RegisteredService found = servicesManager.findServiceBy(clientAppId);
180 assertNotNull(found);
181 assertTrue(found instanceof OidcRegisteredService);
182 OidcRegisteredService oidc = OidcRegisteredService.class.cast(found);
183 OIDCRPClientAppTO oidcrpto = OIDCRPClientAppTO.class.cast(waClientApp.getClientAppTO());
184 assertEquals("uri1|uri2", oidc.getServiceId());
185 assertEquals(oidcrpto.getClientId(), oidc.getClientId());
186 assertEquals(oidcrpto.getClientSecret(), oidc.getClientSecret());
187 assertTrue(oidc.getAuthenticationPolicy().getRequiredAuthenticationHandlers().contains("TestAuthModule"));
188 assertTrue(((AnyAuthenticationHandlerRegisteredServiceAuthenticationPolicyCriteria) oidc.
189 getAuthenticationPolicy().getCriteria()).isTryAll());
190 assertTrue(oidc.getAttributeReleasePolicy() instanceof ChainingAttributeReleasePolicy);
191 assertEquals(RegisteredServiceLogoutType.valueOf(oidcrpto.getLogoutType().name()), oidc.getLogoutType());
192
193
194 waClientApp = new WAClientApp();
195 waClientApp.setClientAppTO(buildSAML2SP());
196 clientAppId = waClientApp.getClientAppTO().getClientAppId();
197 addPolicies(waClientApp, true);
198
199 SyncopeCoreTestingServer.CLIENT_APPS.add(waClientApp);
200 apps = service.list();
201 assertEquals(2, apps.size());
202
203 load = servicesManager.load();
204 assertEquals(4, load.size());
205
206 found = servicesManager.findServiceBy(clientAppId);
207 assertTrue(found instanceof SamlRegisteredService);
208 SamlRegisteredService saml = SamlRegisteredService.class.cast(found);
209 SAML2SPClientAppTO samlspto = SAML2SPClientAppTO.class.cast(waClientApp.getClientAppTO());
210 assertEquals(samlspto.getMetadataLocation(), saml.getMetadataLocation());
211 assertEquals(samlspto.getEntityId(), saml.getServiceId());
212 assertTrue(saml.getAuthenticationPolicy().getRequiredAuthenticationHandlers().contains("TestAuthModule"));
213 assertNotNull(found.getAccessStrategy());
214 assertTrue(saml.getAttributeReleasePolicy() instanceof ChainingAttributeReleasePolicy);
215 assertEquals(RegisteredServiceLogoutType.valueOf(samlspto.getLogoutType().name()), saml.getLogoutType());
216
217 waClientApp = new WAClientApp();
218 waClientApp.setClientAppTO(buildSAML2SP());
219 clientAppId = waClientApp.getClientAppTO().getClientAppId();
220 addPolicies(waClientApp, false);
221
222 SyncopeCoreTestingServer.CLIENT_APPS.add(waClientApp);
223 apps = service.list();
224 assertEquals(3, apps.size());
225
226 load = servicesManager.load();
227 assertEquals(5, load.size());
228
229 found = servicesManager.findServiceBy(clientAppId);
230 assertTrue(found.getAttributeReleasePolicy() instanceof DenyAllAttributeReleasePolicy);
231 }
232
233 @Test
234 public void delegatedAuthentication() {
235
236 OIDCAuthModuleConf oidcAuthModuleConf = new OIDCAuthModuleConf();
237 oidcAuthModuleConf.setClientId("clientId");
238 oidcAuthModuleConf.setClientSecret("clientSecret");
239 AuthModuleTO authModuleTO = new AuthModuleTO();
240 authModuleTO.setKey("keycloack");
241 authModuleTO.setConf(oidcAuthModuleConf);
242
243 SyncopeCoreTestingServer.AUTH_MODULES.clear();
244 SyncopeCoreTestingServer.AUTH_MODULES.add(authModuleTO);
245 AuthModuleService authModuleService = waRestClient.getService(AuthModuleService.class);
246 assertEquals(1, authModuleService.list().size());
247
248 SyncopeCoreTestingServer.CLIENT_APPS.clear();
249 WAClientAppService waClientAppService = waRestClient.getService(WAClientAppService.class);
250 assertTrue(waClientAppService.list().isEmpty());
251
252 WAClientApp waClientApp = new WAClientApp();
253 waClientApp.setClientAppTO(buildOIDCRP());
254 waClientApp.getAuthModules().add(0, authModuleTO);
255 Long clientAppId = waClientApp.getClientAppTO().getClientAppId();
256 addPolicies(waClientApp, false);
257 DefaultAuthPolicyConf authPolicyConf = (DefaultAuthPolicyConf) waClientApp.getAuthPolicy().getConf();
258 authPolicyConf.getAuthModules().clear();
259 authPolicyConf.getAuthModules().add(authModuleTO.getKey());
260 SyncopeCoreTestingServer.CLIENT_APPS.add(waClientApp);
261
262
263 int before = authenticationEventExecutionPlan.getObject().getAuthenticationHandlers().size();
264
265 contextRefresher.refresh();
266
267 int after = authenticationEventExecutionPlan.getObject().getAuthenticationHandlers().size();
268 assertEquals(before + 1, after);
269
270
271 RegisteredService service = servicesManager.findServiceBy(clientAppId);
272 assertNotNull(service);
273
274 assertEquals(
275 Set.of("TestAuthModule", "DelegatedClientAuthenticationHandler"),
276 service.getAuthenticationPolicy().getRequiredAuthenticationHandlers());
277
278 RegisteredServiceAccessStrategy accessStrategy = service.getAccessStrategy();
279 assertNotNull(accessStrategy);
280 RegisteredServiceDelegatedAuthenticationPolicy delegatedAuthPolicy =
281 accessStrategy.getDelegatedAuthenticationPolicy();
282 assertNotNull(delegatedAuthPolicy);
283 assertEquals(1, delegatedAuthPolicy.getAllowedProviders().size());
284 assertTrue(delegatedAuthPolicy.getAllowedProviders().contains(authModuleTO.getKey()));
285
286 assertNotNull(service.getTicketGrantingTicketExpirationPolicy());
287 }
288 }