PageRenderTime 63ms CodeModel.GetById 28ms RepoModel.GetById 0ms app.codeStats 0ms

/core-model-test/tests/src/test/java/org/jboss/as/core/model/test/access/RoleMappingTestCase.java

https://github.com/dbuos/wildfly
Java | 546 lines | 374 code | 96 blank | 76 comment | 8 complexity | bd2d3dc4147c50abaaf817c10b34386f MD5 | raw file
Possible License(s): Apache-2.0
  1. /*
  2. * JBoss, Home of Professional Open Source.
  3. * Copyright 2013, Red Hat, Inc., and individual contributors
  4. * as indicated by the @author tags. See the copyright.txt file in the
  5. * distribution for a full listing of individual contributors.
  6. *
  7. * This is free software; you can redistribute it and/or modify it
  8. * under the terms of the GNU Lesser General Public License as
  9. * published by the Free Software Foundation; either version 2.1 of
  10. * the License, or (at your option) any later version.
  11. *
  12. * This software is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  15. * Lesser General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU Lesser General Public
  18. * License along with this software; if not, write to the Free
  19. * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
  20. * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
  21. */
  22. package org.jboss.as.core.model.test.access;
  23. import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.ACCESS;
  24. import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.ADD;
  25. import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.AUTHORIZATION;
  26. import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.CORE_SERVICE;
  27. import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.INCLUDE_ALL;
  28. import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.MANAGEMENT;
  29. import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.NAME;
  30. import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.OP;
  31. import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.OP_ADDR;
  32. import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.OUTCOME;
  33. import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.REALM;
  34. import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.REMOVE;
  35. import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.RESULT;
  36. import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.ROLE_MAPPING;
  37. import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.SUCCESS;
  38. import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.FAILED;
  39. import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.TYPE;
  40. import static org.jboss.as.domain.management.ModelDescriptionConstants.IS_CALLER_IN_ROLE;
  41. import static org.junit.Assert.assertEquals;
  42. import java.security.Principal;
  43. import java.security.PrivilegedAction;
  44. import java.util.Set;
  45. import javax.security.auth.Subject;
  46. import org.jboss.as.controller.descriptions.ModelDescriptionConstants;
  47. import org.jboss.as.core.model.test.AbstractCoreModelTest;
  48. import org.jboss.as.core.model.test.KernelServices;
  49. import org.jboss.as.core.model.test.TestModelType;
  50. import org.jboss.as.core.security.AccountPrincipal;
  51. import org.jboss.as.core.security.GroupPrincipal;
  52. import org.jboss.as.core.security.RealmPrincipal;
  53. import org.jboss.dmr.ModelNode;
  54. import org.junit.Before;
  55. import org.junit.Test;
  56. /**
  57. * Test case to test the role mapping behaviour (model and runtime mapping).
  58. *
  59. * @author <a href="mailto:darran.lofthouse@jboss.com">Darran Lofthouse</a>
  60. */
  61. public class RoleMappingTestCase extends AbstractCoreModelTest {
  62. private static final String TEST_REALM = "TestRealm";
  63. private static final String OTHER_REALM = "OtherRealm";
  64. private static final String OTHER_USER = "OtherUser";
  65. private KernelServices kernelServices;
  66. private int uniqueCount = 0;
  67. @Before
  68. public void setUp() throws Exception {
  69. kernelServices = createKernelServicesBuilder(TestModelType.STANDALONE)
  70. .setXmlResource("constraints.xml")
  71. .validateDescription()
  72. .build();
  73. }
  74. /**
  75. * Test that a user is assigned a role based on their username (not realm specific).
  76. *
  77. * Also verify that assignment of a group with the same name does not result in role assignment.
  78. */
  79. @Test
  80. public void testIncludeByUsername() {
  81. final String roleName = "Deployer";
  82. final String userName = "UserOne";
  83. addRole(roleName, false);
  84. addPrincipal(roleName, MappingType.INCLUDE, PrincipalType.USER, userName, null);
  85. assertIsCallerInRole(roleName, null, false);
  86. assertIsCallerInRole(roleName, true, userName, TEST_REALM, null);
  87. assertIsCallerInRole(roleName, false, OTHER_USER, TEST_REALM, null, userName);
  88. removeRole(roleName);
  89. }
  90. /**
  91. * Same as testIncludeByUsername but now verify that the users realm is taken into account.
  92. */
  93. @Test
  94. public void testIncludeByUsernameAndRealm() {
  95. final String roleName = "Deployer";
  96. final String userName = "UserTwo";
  97. addRole(roleName, false);
  98. addPrincipal(roleName, MappingType.INCLUDE, PrincipalType.USER, userName, TEST_REALM);
  99. assertIsCallerInRole(roleName, null, false);
  100. assertIsCallerInRole(roleName, true, userName, TEST_REALM, null);
  101. assertIsCallerInRole(roleName, false, userName, OTHER_REALM, null);
  102. assertIsCallerInRole(roleName, false, OTHER_USER, TEST_REALM, null, userName);
  103. removeRole(roleName);
  104. }
  105. /**
  106. * Test that a user is assigned a role based on their group membership (not realm specific).
  107. *
  108. * Also verify that a user account with the same name does not result in role assignment.
  109. */
  110. @Test
  111. public void testIncludeByGroup() {
  112. final String roleName = "Deployer";
  113. final String userName = "UserThree";
  114. final String groupName = "GroupThree";
  115. addRole(roleName, false);
  116. addPrincipal(roleName, MappingType.INCLUDE, PrincipalType.GROUP, groupName, null);
  117. assertIsCallerInRole(roleName, null, false);
  118. assertIsCallerInRole(roleName, true, userName, TEST_REALM, null, groupName);
  119. assertIsCallerInRole(roleName, true, userName, OTHER_REALM, null, groupName);
  120. assertIsCallerInRole(roleName, false, groupName, TEST_REALM, null, userName);
  121. removeRole(roleName);
  122. }
  123. /**
  124. * Same as testIncludeByGroup but now include the realm name in the match.
  125. */
  126. @Test
  127. public void testIncludeByGroupAndRealm() {
  128. final String roleName = "Deployer";
  129. final String userName = "UserFour";
  130. final String groupName = "GroupFour";
  131. addRole(roleName, false);
  132. addPrincipal(roleName, MappingType.INCLUDE, PrincipalType.GROUP, groupName, TEST_REALM);
  133. assertIsCallerInRole(roleName, null, false);
  134. assertIsCallerInRole(roleName, true, userName, TEST_REALM, null, groupName);
  135. assertIsCallerInRole(roleName, false, userName, OTHER_REALM, null, groupName);
  136. assertIsCallerInRole(roleName, false, groupName, TEST_REALM, null, userName);
  137. removeRole(roleName);
  138. }
  139. /**
  140. * Test that a user matched to a role by group is not assigned the role if their username is in the exclude list.
  141. */
  142. @Test
  143. public void testExcludeByUsername() {
  144. final String roleName = "Deployer";
  145. final String userName = "UserFive";
  146. final String groupName = "GroupFive";
  147. addRole(roleName, false);
  148. addPrincipal(roleName, MappingType.INCLUDE, PrincipalType.GROUP, groupName, null);
  149. addPrincipal(roleName, MappingType.EXCLUDE, PrincipalType.USER, userName, null);
  150. assertIsCallerInRole(roleName, null, false);
  151. assertIsCallerInRole(roleName, true, OTHER_USER, TEST_REALM, null, groupName);
  152. assertIsCallerInRole(roleName, false, userName, TEST_REALM, null, groupName);
  153. removeRole(roleName);
  154. }
  155. /**
  156. * Same as testExcludeByUsername except the exclusion is realm specific.
  157. */
  158. @Test
  159. public void testExcludeByUsernameAndRealm() {
  160. final String roleName = "Deployer";
  161. final String userName = "UserFive";
  162. final String groupName = "GroupFive";
  163. addRole(roleName, false);
  164. addPrincipal(roleName, MappingType.INCLUDE, PrincipalType.GROUP, groupName, null);
  165. addPrincipal(roleName, MappingType.EXCLUDE, PrincipalType.USER, userName, TEST_REALM);
  166. assertIsCallerInRole(roleName, null, false);
  167. assertIsCallerInRole(roleName, true, OTHER_USER, TEST_REALM, null, groupName);
  168. assertIsCallerInRole(roleName, false, userName, TEST_REALM, null, groupName);
  169. assertIsCallerInRole(roleName, true, userName, OTHER_REALM, null, groupName);
  170. removeRole(roleName);
  171. }
  172. /**
  173. * Test that a user assigned a role due to group membership is excluded based on the membership of another group.
  174. */
  175. @Test
  176. public void testExcludeByGroup() {
  177. final String roleName = "Deployer";
  178. final String userName = "UserSix";
  179. final String inGroupName = "GroupSix_In";
  180. final String outGroupName = "GroupSix_Out";
  181. addRole(roleName, false);
  182. addPrincipal(roleName, MappingType.INCLUDE, PrincipalType.GROUP, inGroupName, null);
  183. addPrincipal(roleName, MappingType.EXCLUDE, PrincipalType.GROUP, outGroupName, null);
  184. assertIsCallerInRole(roleName, null, false);
  185. assertIsCallerInRole(roleName, true, userName, TEST_REALM, null, inGroupName);
  186. assertIsCallerInRole(roleName, false, userName, TEST_REALM, null, inGroupName, outGroupName);
  187. removeRole(roleName);
  188. }
  189. /**
  190. * Same as testExcludeByGroup but the exclusion takes the realm into account.
  191. */
  192. @Test
  193. public void testExcludeByGroupAndRealm() {
  194. final String roleName = "Deployer";
  195. final String userName = "UserSeven";
  196. final String inGroupName = "GroupSeven_In";
  197. final String outGroupName = "GroupSeven_Out";
  198. addRole(roleName, false);
  199. addPrincipal(roleName, MappingType.INCLUDE, PrincipalType.GROUP, inGroupName, null);
  200. addPrincipal(roleName, MappingType.EXCLUDE, PrincipalType.GROUP, outGroupName, TEST_REALM);
  201. assertIsCallerInRole(roleName, null, false);
  202. assertIsCallerInRole(roleName, true, userName, TEST_REALM, null, inGroupName);
  203. assertIsCallerInRole(roleName, false, userName, TEST_REALM, null, inGroupName, outGroupName);
  204. assertIsCallerInRole(roleName, true, userName, OTHER_REALM, null, inGroupName, outGroupName);
  205. removeRole(roleName);
  206. }
  207. /**
  208. * Test that user assigned the SUPERUSER role can actually request a different role.
  209. *
  210. * On requesting the different role the user should not be assigned the SUPERUSER role anymore.
  211. */
  212. @Test
  213. public void testSuperUserAs() {
  214. final String roleName = "SuperUser";
  215. final String otherRole = "Deployer";
  216. final String userName = "UserThirteen";
  217. addRole(roleName, false);
  218. ModelNode addedAddress = addPrincipal(roleName, MappingType.INCLUDE, PrincipalType.USER, userName, null);
  219. assertIsCallerInRole(roleName, true, userName, TEST_REALM, null);
  220. assertIsCallerInRole(otherRole, true, userName, TEST_REALM, otherRole);
  221. assertIsCallerInRole(roleName, false, userName, TEST_REALM, otherRole);
  222. removePrincipal(addedAddress);
  223. removeRole(roleName);
  224. }
  225. /**
  226. * Test that user assigned the Deployer role can NOT request a different role.
  227. */
  228. @Test
  229. public void testDeployerAs() {
  230. final String roleName = "Deployer";
  231. final String otherRole = "MONITOR";
  232. final String userName = "UserFourteen";
  233. addRole(roleName, false);
  234. ModelNode addedAddress = addPrincipal(roleName, MappingType.INCLUDE, PrincipalType.USER, userName, null);
  235. assertIsCallerInRole(roleName, true, userName, TEST_REALM, null);
  236. assertIsCallerInRole(otherRole, false, userName, TEST_REALM, otherRole);
  237. assertIsCallerInRole(roleName, true, userName, TEST_REALM, otherRole);
  238. removePrincipal(addedAddress);
  239. removeRole(roleName);
  240. }
  241. /**
  242. * Test that an authenticated user is assigned a role where include-all = true.
  243. */
  244. @Test
  245. public void testIncludeAll() {
  246. final String roleName = "Deployer";
  247. final String userName = "UserEight";
  248. addRole(roleName, true);
  249. assertIsCallerInRole(roleName, null, false);
  250. assertIsCallerInRole(roleName, true, userName, TEST_REALM, null);
  251. removeRole(roleName);
  252. }
  253. /**
  254. * Test that a user matched to a role by include-all is not assigned the role if their username is in the exclude list.
  255. */
  256. @Test
  257. public void testIncludeAll_ExcludeByUsername() {
  258. final String roleName = "Deployer";
  259. final String userName = "UserNine";
  260. final String groupName = "GroupNine";
  261. addRole(roleName, true);
  262. addPrincipal(roleName, MappingType.EXCLUDE, PrincipalType.USER, userName, null);
  263. assertIsCallerInRole(roleName, null, false);
  264. assertIsCallerInRole(roleName, true, OTHER_USER, TEST_REALM, null, groupName);
  265. assertIsCallerInRole(roleName, false, userName, TEST_REALM, null, groupName);
  266. removeRole(roleName);
  267. }
  268. /**
  269. * Test that a user matched to a role by include-all is not assigned the role if their group is in the exclude list.
  270. */
  271. @Test
  272. public void testIncludeAll_ExcludeByGroup() {
  273. final String roleName = "Deployer";
  274. final String userName = "UserTen";
  275. final String groupName = "GroupTen";
  276. addRole(roleName, true);
  277. addPrincipal(roleName, MappingType.EXCLUDE, PrincipalType.GROUP, groupName, null);
  278. assertIsCallerInRole(roleName, null, false);
  279. assertIsCallerInRole(roleName, true, userName, TEST_REALM, null);
  280. assertIsCallerInRole(roleName, false, userName, TEST_REALM, null, groupName);
  281. removeRole(roleName);
  282. }
  283. /*
  284. * Duplicate Handling
  285. *
  286. * Tests to verify that the add operations successfully detect duplicate include/exclude definitions.
  287. */
  288. @Test
  289. public void testDuplicateUserComplete() {
  290. final String roleName = "Deployer";
  291. final String userName = "UserEleven";
  292. addRole(roleName, false);
  293. addPrincipal(roleName, MappingType.INCLUDE, PrincipalType.USER, userName, TEST_REALM);
  294. addPrincipal(roleName, MappingType.INCLUDE, PrincipalType.USER, userName, TEST_REALM, true);
  295. removeRole(roleName);
  296. }
  297. @Test
  298. public void testDuplicateUserRealmLess() {
  299. final String roleName = "Deployer";
  300. final String userName = "UserTwelve";
  301. addRole(roleName, false);
  302. addPrincipal(roleName, MappingType.INCLUDE, PrincipalType.USER, userName, null);
  303. addPrincipal(roleName, MappingType.INCLUDE, PrincipalType.USER, userName, TEST_REALM);
  304. addPrincipal(roleName, MappingType.INCLUDE, PrincipalType.USER, userName, null, true);
  305. addPrincipal(roleName, MappingType.EXCLUDE, PrincipalType.USER, userName, TEST_REALM);
  306. addPrincipal(roleName, MappingType.EXCLUDE, PrincipalType.USER, userName, null);
  307. addPrincipal(roleName, MappingType.EXCLUDE, PrincipalType.USER, userName, null, true);
  308. removeRole(roleName);
  309. }
  310. @Test
  311. public void testDuplicateGroupComplete() {
  312. final String roleName = "Deployer";
  313. final String groupName = "UserThirteen";
  314. addRole(roleName, false);
  315. addPrincipal(roleName, MappingType.EXCLUDE, PrincipalType.GROUP, groupName, TEST_REALM);
  316. addPrincipal(roleName, MappingType.EXCLUDE, PrincipalType.GROUP, groupName, TEST_REALM, true);
  317. removeRole(roleName);
  318. }
  319. @Test
  320. public void testDuplicateGroupRealmLess() {
  321. final String roleName = "Deployer";
  322. final String groupName = "UserFourteen";
  323. addRole(roleName, false);
  324. addPrincipal(roleName, MappingType.EXCLUDE, PrincipalType.GROUP, groupName, null);
  325. addPrincipal(roleName, MappingType.EXCLUDE, PrincipalType.GROUP, groupName, TEST_REALM);
  326. addPrincipal(roleName, MappingType.EXCLUDE, PrincipalType.GROUP, groupName, null, true);
  327. addPrincipal(roleName, MappingType.INCLUDE, PrincipalType.GROUP, groupName, TEST_REALM);
  328. addPrincipal(roleName, MappingType.INCLUDE, PrincipalType.GROUP, groupName, null);
  329. addPrincipal(roleName, MappingType.INCLUDE, PrincipalType.GROUP, groupName, null, true);
  330. removeRole(roleName);
  331. }
  332. private void addRole(final String roleName, boolean includeAll) {
  333. ModelNode operation = new ModelNode();
  334. operation.get(OP_ADDR).add(CORE_SERVICE, MANAGEMENT).add(ACCESS, AUTHORIZATION).add(ROLE_MAPPING, roleName);
  335. operation.get(OP).set(ADD);
  336. if (includeAll) {
  337. operation.get(INCLUDE_ALL).set(true);
  338. }
  339. ModelNode response = kernelServices.executeOperation(operation);
  340. assertEquals(SUCCESS, response.get(OUTCOME).asString());
  341. }
  342. private ModelNode addPrincipal(final String roleName, final MappingType mappingType, final PrincipalType principalType, final String name, final String realm) {
  343. return addPrincipal(roleName, mappingType, principalType, name, realm, false);
  344. }
  345. private ModelNode addPrincipal(final String roleName, final MappingType mappingType, final PrincipalType principalType, final String name, final String realm, boolean expectFailure) {
  346. ModelNode operation = new ModelNode();
  347. operation.get(OP_ADDR).add(CORE_SERVICE, MANAGEMENT).add(ACCESS, AUTHORIZATION).add(ROLE_MAPPING, roleName).add(mappingType.toString(), uniqueCount++);
  348. operation.get(OP).set(ADD);
  349. operation.get(TYPE).set(principalType.toString());
  350. operation.get(NAME).set(name);
  351. if (realm != null) {
  352. operation.get(REALM).set(realm);
  353. }
  354. ModelNode response = kernelServices.executeOperation(operation);
  355. if (expectFailure) {
  356. assertEquals(FAILED, response.get(OUTCOME).asString());
  357. } else {
  358. assertEquals(SUCCESS, response.get(OUTCOME).asString());
  359. }
  360. return operation.get(OP_ADDR);
  361. }
  362. private void removePrincipal(final ModelNode address) {
  363. ModelNode operation = new ModelNode();
  364. operation.get(OP_ADDR).set(address);
  365. operation.get(OP).set(REMOVE);
  366. ModelNode response = kernelServices.executeOperation(operation);
  367. assertEquals(SUCCESS, response.get(OUTCOME).asString());
  368. }
  369. private void removeRole(final String roleName) {
  370. ModelNode operation = new ModelNode();
  371. operation.get(OP_ADDR).add(CORE_SERVICE, MANAGEMENT).add(ACCESS, AUTHORIZATION).add(ROLE_MAPPING, roleName);
  372. operation.get(OP).set(REMOVE);
  373. ModelNode response = kernelServices.executeOperation(operation);
  374. assertEquals(SUCCESS, response.get(OUTCOME).asString());
  375. }
  376. private void assertIsCallerInRole(final String roleName, final String runAsRole, final boolean expectedOutcome) {
  377. ModelNode operation = new ModelNode();
  378. operation.get(OP_ADDR).add(CORE_SERVICE, MANAGEMENT).add(ACCESS, AUTHORIZATION).add(ROLE_MAPPING, roleName);
  379. operation.get(OP).set(IS_CALLER_IN_ROLE);
  380. if (runAsRole != null) {
  381. ModelNode headers = operation.get(ModelDescriptionConstants.OPERATION_HEADERS);
  382. headers.get("roles").set(runAsRole);
  383. }
  384. ModelNode response = kernelServices.executeOperation(operation);
  385. assertEquals(SUCCESS, response.get(OUTCOME).asString());
  386. assertEquals(expectedOutcome, response.get(RESULT).asBoolean());
  387. }
  388. private void assertIsCallerInRole(final String roleName, final boolean expectedOutcome, final String userName,
  389. final String realm, final String runAsRole, final String... groups) {
  390. Subject subject = new Subject();
  391. Set<Principal> principals = subject.getPrincipals();
  392. principals.add(new User(userName, realm));
  393. for (String current : groups) {
  394. principals.add(new Group(current, realm));
  395. }
  396. Subject.doAs(subject, new PrivilegedAction<Void>() {
  397. @Override
  398. public Void run() {
  399. assertIsCallerInRole(roleName, runAsRole, expectedOutcome);
  400. return null;
  401. }
  402. });
  403. }
  404. private enum PrincipalType {
  405. GROUP, USER;
  406. @Override
  407. public String toString() {
  408. return super.toString().toLowerCase();
  409. }
  410. }
  411. private enum MappingType {
  412. EXCLUDE, INCLUDE;
  413. @Override
  414. public String toString() {
  415. return super.toString().toLowerCase();
  416. }
  417. }
  418. private static class User implements RealmPrincipal, AccountPrincipal {
  419. private final String realm;
  420. private final String name;
  421. private User(final String name, final String realm) {
  422. this.name = name;
  423. this.realm = realm;
  424. }
  425. @Override
  426. public String getName() {
  427. return name;
  428. }
  429. @Override
  430. public String getRealm() {
  431. return realm;
  432. }
  433. }
  434. private static class Group implements RealmPrincipal, GroupPrincipal {
  435. private final String name;
  436. private final String realm;
  437. private Group(final String name, final String realm) {
  438. this.name = name;
  439. this.realm = realm;
  440. }
  441. @Override
  442. public String getName() {
  443. return name;
  444. }
  445. @Override
  446. public String getRealm() {
  447. return realm;
  448. }
  449. }
  450. }