Pass authNote from authenticator to protocol mapper

Hi, I have a custom authenticator that extends UsernamePasswordForm to retrieve the value of a third input on the login page.

@Override
    protected boolean validateForm(AuthenticationFlowContext context, MultivaluedMap<String, String> formData) {
        try {
            final String codeClient = formData.getFirst(CODE_CLIENT_INPUT);
//            keycloakSession.getContext().getAuthenticationSession().setAuthNote(CODE_CLIENT_INPUT, codeClient);
            context.getAuthenticationSession().setAuthNote(CODE_CLIENT_INPUT, codeClient);
            return super.validateForm(context, formData);
        } catch (Exception e) {
            context.failure(AuthenticationFlowError.INTERNAL_ERROR);
            return false;
        }
    }

now, I need to retrieve this value from my custom protocol mapper which extends AbstractOIDCProtocolMapper and implements OIDCAccessTokenMapper but in the current code, with all the ways I’ve tried, I can’t get it, it’s null. What have I done wrong? Thanks for clarifying

    @Override
    protected void setClaim(IDToken token, ProtocolMapperModel mappingModel,
                            UserSessionModel userSession, KeycloakSession keycloakSession,
                            ClientSessionContext clientSessionContext) {
        MultivaluedMap<String, String> formData = keycloakSession.getContext().getHttpRequest().getDecodedFormParameters();
        String codeClient = "";

//        log.info("setClaim, session={}", keycloakSession.getContext().getAuthenticationSession().getAuthNote("cc"));
        log.info("setClaim, session={}", clientSessionContext.getClientSession().getNote("cc"));

        if (formData.containsKey("cc")) {
            codeClient = formData.getFirst("cc");
            token.setPreferredUsername("ADMIN@" + codeClient);
        }

        List<Activity> activities = fetchActivitiesFromDatabase(userSession.getLoginUsername(), mappingModel, codeClient);

        try {
            OIDCAttributeMapperHelper.mapClaim(token, mappingModel, objectMapper.writeValueAsString(activities));
        } catch (JsonProcessingException e) {
            log.error("setClaim, activities={}, exception={}", activities, e);
            throw new RuntimeException(e);
        }
    }
1 Like

If you’re trying to get something from the authentication to a token, I’d suggest storing it in a User Session Note. There is already a mapper in Keycloak for taking things from User Session Notes and putting them in the token.

Auth Notes are for the authentication flow and will not be present after the flow has completed. Also, you’re getting a Client Session Note in your mapper, which is different from either Auth Notes or User Session Notes.

2 Likes