예제 #1
0
    protected Response loginRequest(
        String relayState, AuthnRequestType requestAbstractType, ClientModel client) {
      SamlClient samlClient = new SamlClient(client);
      // validate destination
      if (requestAbstractType.getDestination() != null
          && !uriInfo.getAbsolutePath().equals(requestAbstractType.getDestination())) {
        event.detail(Details.REASON, "invalid_destination");
        event.error(Errors.INVALID_SAML_AUTHN_REQUEST);
        return ErrorPage.error(session, Messages.INVALID_REQUEST);
      }
      String bindingType = getBindingType(requestAbstractType);
      if (samlClient.forcePostBinding()) bindingType = SamlProtocol.SAML_POST_BINDING;
      String redirect = null;
      URI redirectUri = requestAbstractType.getAssertionConsumerServiceURL();
      if (redirectUri != null && !"null".equals(redirectUri)) { // "null" is for testing purposes
        redirect = RedirectUtils.verifyRedirectUri(uriInfo, redirectUri.toString(), realm, client);
      } else {
        if (bindingType.equals(SamlProtocol.SAML_POST_BINDING)) {
          redirect = client.getAttribute(SamlProtocol.SAML_ASSERTION_CONSUMER_URL_POST_ATTRIBUTE);
        } else {
          redirect =
              client.getAttribute(SamlProtocol.SAML_ASSERTION_CONSUMER_URL_REDIRECT_ATTRIBUTE);
        }
        if (redirect == null) {
          redirect = client.getManagementUrl();
        }
      }

      if (redirect == null) {
        event.error(Errors.INVALID_REDIRECT_URI);
        return ErrorPage.error(session, Messages.INVALID_REDIRECT_URI);
      }

      ClientSessionModel clientSession = session.sessions().createClientSession(realm, client);
      clientSession.setAuthMethod(SamlProtocol.LOGIN_PROTOCOL);
      clientSession.setRedirectUri(redirect);
      clientSession.setAction(ClientSessionModel.Action.AUTHENTICATE.name());
      clientSession.setNote(SamlProtocol.SAML_BINDING, bindingType);
      clientSession.setNote(GeneralConstants.RELAY_STATE, relayState);
      clientSession.setNote(SamlProtocol.SAML_REQUEST_ID, requestAbstractType.getID());

      // Handle NameIDPolicy from SP
      NameIDPolicyType nameIdPolicy = requestAbstractType.getNameIDPolicy();
      if (nameIdPolicy != null && !samlClient.forceNameIDFormat()) {
        String nameIdFormat = nameIdPolicy.getFormat().toString();
        // TODO: Handle AllowCreate too, relevant for persistent NameID.
        if (isSupportedNameIdFormat(nameIdFormat)) {
          clientSession.setNote(GeneralConstants.NAMEID_FORMAT, nameIdFormat);
        } else {
          event.detail(Details.REASON, "unsupported_nameid_format");
          event.error(Errors.INVALID_SAML_AUTHN_REQUEST);
          return ErrorPage.error(session, Messages.UNSUPPORTED_NAME_ID_FORMAT);
        }
      }

      // Reading subject/nameID in the saml request
      SubjectType subject = requestAbstractType.getSubject();
      if (subject != null) {
        SubjectType.STSubType subType = subject.getSubType();
        if (subType != null) {
          BaseIDAbstractType baseID = subject.getSubType().getBaseID();
          if (baseID != null && baseID instanceof NameIDType) {
            NameIDType nameID = (NameIDType) baseID;
            clientSession.setNote(OIDCLoginProtocol.LOGIN_HINT_PARAM, nameID.getValue());
          }
        }
      }

      return newBrowserAuthentication(
          clientSession, requestAbstractType.isIsPassive(), redirectToAuthentication);
    }
  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;
  }