Gaurav
Gaurav

Reputation: 33

unable to get configured roles from IDP ( Azure Ad App roles ) when authenticating oidc (pac4j-oidc ) in servlet based application

I am using javaee-pac4j:7.1.0 and pac4j-oidc:5.7.0 to my application authenticated using OIDC ( Azure AD initially ) in servlet based application , i am able to redirect to azure for authentication and callback api is also getting called with logged in user details. but not getting clue on how to get appRoles as defined azure AD . in my flow i need app Roles and then have to create the user and role mapping in my application.

i followed jee-pac4j-demo to get this working but not getting clue on getting app roles from IDP OIDC. Please advise.

below is my web.xml

<filter>
        <filter-name>callbackFilter</filter-name>
        <filter-class>com.xxx.yyy.security.oidc.CallbackFilter</filter-class>

        <init-param>
            <param-name>renewSession</param-name>
            <param-value>true</param-value>
        </init-param>
        <init-param>
            <param-name>multiProfile</param-name>
            <param-value>true</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>callbackFilter</filter-name>
        <url-pattern>/oidc/rest/*</url-pattern>
        <dispatcher>REQUEST</dispatcher>
    </filter-mapping>
    <filter>
        <filter-name>JwtParameterFilter</filter-name>
        <filter-class>org.pac4j.jee.filter.SecurityFilter</filter-class>
        <init-param>
            <param-name>configFactory</param-name>
            <param-value>com.xxx.yyy.security.oidc.DemoConfigFactory</param-value>
        </init-param>
        <init-param>
            <param-name>authorizers</param-name>
            <param-value>custom</param-value>
        </init-param>
        <init-param>
            <param-name>clients</param-name>
            <param-value>OidcClient</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>JwtParameterFilter</filter-name>
        <url-pattern>/rest/rest-jwt/*</url-pattern>
        <dispatcher>REQUEST</dispatcher>
    </filter-mapping>

DemoConfigFactory

@Override
    public Config build(final Object... parameters) {

        System.out.print("Building Security configuration...\n");

         oidcConfiguration = new OidcConfiguration();
        oidcConfiguration.setClientId("sdfdsf-02f9-401f-bbf3-dd87d64a6a2a");
        oidcConfiguration.setSecret("iGc8Q~wZ_~dffsdfsdfs");
        oidcConfiguration.setDiscoveryURI("https://login.microsoftonline.com/sdfsdfs-2cb0-44dc-88cd-fdfs/v2.0/.well-known/openid-configuration");
        oidcConfiguration.setUseNonce(true);
        oidcConfiguration.addCustomParam("prompt", "consent");

        oidcClient = new OidcClient(oidcConfiguration);
       /* oidcClient.setAuthorizationGenerator((webContext, sessionStore, userProfile) -> {
                    userProfile.addRole("ConfiguratorOne");
                    return java.util.Optional.of(userProfile);
                }
                );*/

        // REST authent with JWT for a token passed in the url as the token parameter
        final List<SignatureConfiguration> signatures = new ArrayList<>();
        signatures.add(new SecretSignatureConfiguration(JWT_SALT));
        ParameterClient parameterClient = new ParameterClient("token", new JwtAuthenticator(signatures));
        parameterClient.setSupportGetRequest(true);
        parameterClient.setSupportPostRequest(false);

 final Clients clients = new Clients("https://localhost:8443/myapplication/oidc/rest/sp/consumer", oidcClient);
  final Config config = new Config(clients);
   config.addAuthorizer("custom", new CustomAuthorizer());
        return config;
    }

CallbackFilter.java

@WebFilter(filterName = "CallbackFilter", urlPatterns = {"/oidc/rest/*", "/oidc/rest"})
public class CallbackFilter extends AbstractConfigFilter implements javax.servlet.Filter {

    private static final Log LOG = LogFactory.getLog(CallbackFilter.class);
    private static final String AUTHENTICATED_SESSION_ATTRIBUTE = "authenticated";
    private ProfileManager profileManager;

    @Inject
    private DemoConfigFactory demoConfigFactory;

    @Override
    public void doFilter(final ServletRequest request, final ServletResponse response,
                         final FilterChain chain) throws IOException, ServletException {

        final HttpServletRequest req = (HttpServletRequest) request;
        final HttpServletResponse resp = (HttpServletResponse) response;
        this.internalFilter(req, resp, chain);
        UserProfile userProfile = profileManager.getProfile().get();

        LOG.info("OIDC response received" +userProfile.getUsername());

            LOG.info("" + userProfile.getRoles().toString());
            String authenticatedUser = userProfile.getUsername();
         
            setAuthenticatedSession(req);
            redirectToGotoURL(req, resp, authenticatedUser);

    }

    @Override
    protected void internalFilter(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException {
        Config config = this.getSharedConfig();
        HttpActionAdapter bestAdapter = FindBest.httpActionAdapter((HttpActionAdapter)null, config, JEEHttpActionAdapter.INSTANCE);
        CallbackLogic bestLogic = FindBest.callbackLogic(this.callbackLogic, config, DefaultCallbackLogic.INSTANCE);
        WebContext context = FindBest.webContextFactory((WebContextFactory)null, config, JEEContextFactory.INSTANCE).newContext(new Object[]{request, response});
        SessionStore sessionStore = FindBest.sessionStoreFactory((SessionStoreFactory)null, config, JEESessionStoreFactory.INSTANCE).newSessionStore(new Object[]{request, response});
        bestLogic.perform(context, sessionStore, config, bestAdapter, this.defaultUrl, this.renewSession, this.defaultClient);
        profileManager = new ProfileManager(context,sessionStore);
      
    }

Upvotes: 0

Views: 130

Answers (1)

Gaurav
Gaurav

Reputation: 33

I searched in pac4j documentation and found that i was missing to set the scope in OidcConfiguration object.

oidcConfiguration.setScope("openid email profile phone");

after setting the scope now i am getting the Roles in the claims sent by IDP.

Upvotes: 0

Related Questions