protected String getAttribute( IdentityProviderMapperModel mapperModel, BrokeredIdentityContext context) { String name = mapperModel.getConfig().get(ATTRIBUTE_NAME); if (name != null && name.trim().equals("")) name = null; String friendly = mapperModel.getConfig().get(ATTRIBUTE_FRIENDLY_NAME); if (friendly != null && friendly.trim().equals("")) friendly = null; AssertionType assertion = (AssertionType) context.getContextData().get(SAMLEndpoint.SAML_ASSERTION); for (AttributeStatementType statement : assertion.getAttributeStatements()) { for (AttributeStatementType.ASTChoiceType choice : statement.getAttributes()) { AttributeType attr = choice.getAttribute(); if (name != null && !name.equals(attr.getName())) continue; if (friendly != null && !friendly.equals(attr.getFriendlyName())) continue; List<Object> attributeValue = attr.getAttributeValue(); if (attributeValue == null || attributeValue.isEmpty()) return null; return attributeValue.get(0).toString(); } } return null; }
@Test public void testAttributes() throws Exception { // this test has a hardcoded SAMLRequest and we hack a SP face servlet to get the SAMLResponse // so we can look // at the assertions sent. This is because Picketlink, AFAICT, does not give you any way to get // access to // the assertion. { SamlSPFacade.samlResponse = null; driver.navigate().to("http://*****:*****@redhat.com"); email = true; } else if (attr.getName().equals("phone")) { Assert.assertEquals( JBossSAMLURIConstants.ATTRIBUTE_FORMAT_BASIC.get(), attr.getNameFormat()); Assert.assertEquals(attr.getAttributeValue().get(0), "617"); phone = true; } else if (attr.getName().equals("Role")) { if (attr.getAttributeValue().get(0).equals("manager")) managerRole = true; if (attr.getAttributeValue().get(0).equals("user")) userRole = true; } } } Assert.assertTrue(email); Assert.assertTrue(phone); Assert.assertTrue(userRole); Assert.assertTrue(managerRole); } keycloakRule.update( new KeycloakRule.KeycloakSetup() { @Override public void config( RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) { ClientModel app = appRealm.getClientByClientId("http://localhost:8081/employee/"); for (ProtocolMapperModel mapper : app.getProtocolMappers()) { if (mapper.getName().equals("role-list")) { app.removeProtocolMapper(mapper); mapper.setId(null); mapper.getConfig().put(RoleListMapper.SINGLE_ROLE_ATTRIBUTE, "true"); mapper.getConfig().put(AttributeStatementHelper.SAML_ATTRIBUTE_NAME, "memberOf"); app.addProtocolMapper(mapper); } } app.addProtocolMapper( HardcodedAttributeMapper.create( "hardcoded-attribute", "hardcoded-attribute", "Basic", null, "hard", false, null)); app.addProtocolMapper(HardcodedRole.create("hardcoded-role", "hardcoded-role")); app.addProtocolMapper(RoleNameMapper.create("renamed-role", "manager", "el-jefe")); app.addProtocolMapper( RoleNameMapper.create( "renamed-employee-role", "http://localhost:8081/employee/.employee", "pee-on")); } }, "demo"); System.out.println(">>>>>>>>>> single role attribute <<<<<<<<"); { SamlSPFacade.samlResponse = null; driver.navigate().to("http://localhost:8081/employee/"); System.out.println(driver.getCurrentUrl()); Assert.assertEquals(driver.getCurrentUrl(), "http://localhost:8081/employee/"); Assert.assertNotNull(SamlSPFacade.samlResponse); SAML2Response saml2Response = new SAML2Response(); byte[] samlResponse = PostBindingUtil.base64Decode(SamlSPFacade.samlResponse); ResponseType rt = saml2Response.getResponseType(new ByteArrayInputStream(samlResponse)); Assert.assertTrue(rt.getAssertions().size() == 1); AssertionType assertion = rt.getAssertions().get(0).getAssertion(); // test attributes and roles boolean userRole = false; boolean managerRole = false; boolean single = false; boolean hardcodedRole = false; boolean hardcodedAttribute = false; boolean peeOn = false; for (AttributeStatementType statement : assertion.getAttributeStatements()) { for (AttributeStatementType.ASTChoiceType choice : statement.getAttributes()) { AttributeType attr = choice.getAttribute(); if (attr.getName().equals("memberOf")) { if (single) Assert.fail("too many role attributes"); single = true; for (Object value : attr.getAttributeValue()) { if (value.equals("el-jefe")) managerRole = true; if (value.equals("user")) userRole = true; if (value.equals("hardcoded-role")) hardcodedRole = true; if (value.equals("pee-on")) peeOn = true; } } else if (attr.getName().equals("hardcoded-attribute")) { hardcodedAttribute = true; Assert.assertEquals(attr.getAttributeValue().get(0), "hard"); } } } Assert.assertTrue(single); Assert.assertTrue(hardcodedAttribute); Assert.assertTrue(hardcodedRole); Assert.assertTrue(peeOn); Assert.assertTrue(userRole); Assert.assertTrue(managerRole); } }
protected AuthOutcome handleLoginResponse( ResponseType responseType, OnSessionCreated onCreateSession) { AssertionType assertion = null; try { assertion = AssertionUtil.getAssertion(responseType, deployment.getDecryptionKey()); if (AssertionUtil.hasExpired(assertion)) { return initiateLogin(); } } catch (Exception e) { log.error("Error extracting SAML assertion: " + e.getMessage()); challenge = new AuthChallenge() { @Override public boolean challenge(HttpFacade exchange) { SamlAuthenticationError error = new SamlAuthenticationError(SamlAuthenticationError.Reason.EXTRACTION_FAILURE); exchange.getRequest().setError(error); exchange.getResponse().sendError(403); return true; } @Override public int getResponseCode() { return 403; } }; } SubjectType subject = assertion.getSubject(); SubjectType.STSubType subType = subject.getSubType(); NameIDType subjectNameID = (NameIDType) subType.getBaseID(); String principalName = subjectNameID.getValue(); final Set<String> roles = new HashSet<>(); MultivaluedHashMap<String, String> attributes = new MultivaluedHashMap<>(); MultivaluedHashMap<String, String> friendlyAttributes = new MultivaluedHashMap<>(); Set<StatementAbstractType> statements = assertion.getStatements(); for (StatementAbstractType statement : statements) { if (statement instanceof AttributeStatementType) { AttributeStatementType attributeStatement = (AttributeStatementType) statement; List<AttributeStatementType.ASTChoiceType> attList = attributeStatement.getAttributes(); for (AttributeStatementType.ASTChoiceType obj : attList) { AttributeType attr = obj.getAttribute(); if (isRole(attr)) { List<Object> attributeValues = attr.getAttributeValue(); if (attributeValues != null) { for (Object attrValue : attributeValues) { String role = getAttributeValue(attrValue); log.debugv("Add role: {0}", role); roles.add(role); } } } else { List<Object> attributeValues = attr.getAttributeValue(); if (attributeValues != null) { for (Object attrValue : attributeValues) { String value = getAttributeValue(attrValue); if (attr.getName() != null) { attributes.add(attr.getName(), value); } if (attr.getFriendlyName() != null) { friendlyAttributes.add(attr.getFriendlyName(), value); } } } } } } } if (deployment.getPrincipalNamePolicy() == SamlDeployment.PrincipalNamePolicy.FROM_ATTRIBUTE) { if (deployment.getPrincipalAttributeName() != null) { String attribute = attributes.getFirst(deployment.getPrincipalAttributeName()); if (attribute != null) principalName = attribute; else { attribute = friendlyAttributes.getFirst(deployment.getPrincipalAttributeName()); if (attribute != null) principalName = attribute; } } } AuthnStatementType authn = null; for (Object statement : assertion.getStatements()) { if (statement instanceof AuthnStatementType) { authn = (AuthnStatementType) statement; break; } } URI nameFormat = subjectNameID.getFormat(); String nameFormatString = nameFormat == null ? JBossSAMLURIConstants.NAMEID_FORMAT_UNSPECIFIED.get() : nameFormat.toString(); final SamlPrincipal principal = new SamlPrincipal( assertion, principalName, principalName, nameFormatString, attributes, friendlyAttributes); String index = authn == null ? null : authn.getSessionIndex(); final String sessionIndex = index; SamlSession account = new SamlSession(principal, roles, sessionIndex); sessionStore.saveAccount(account); onCreateSession.onSessionCreated(account); // redirect to original request, it will be restored String redirectUri = sessionStore.getRedirectUri(); if (redirectUri != null) { facade.getResponse().setHeader("Location", redirectUri); facade.getResponse().setStatus(302); facade.getResponse().end(); } else { log.debug("IDP initiated invocation"); } log.debug("AUTHENTICATED authn"); return AuthOutcome.AUTHENTICATED; }