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

huangapple go评论122阅读模式
英文:

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

问题

我正在使用 javaee-pac4j:7.1.0 和 pac4j-oidc:5.7.0 来对我的应用程序进行 OIDC 认证(最初使用 Azure AD)。在基于 Servlet 的应用程序中,我能够重定向到 Azure 进行认证,并且回调 API 也会被调用,其中包含已登录用户的详细信息。但是我不知道如何获取 Azure AD 中定义的 appRoles。在我的流程中,我需要获取 appRoles,然后在我的应用程序中创建用户和角色映射。

我按照 jee-pac4j-demo 来使这个工作,但是不知道如何从 IDP OIDC 获取 appRoles。请提供建议。

以下是我的 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.java:

@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);
      
    }
}

请注意,这是您提供的代码和文本的翻译。如果您有任何其他问题或需要进一步的帮助,请随时告诉我。

英文:

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

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

DemoConfigFactory

@Override
public Config build(final Object... parameters) {
System.out.print(&quot;Building Security configuration...\n&quot;);
oidcConfiguration = new OidcConfiguration();
oidcConfiguration.setClientId(&quot;sdfdsf-02f9-401f-bbf3-dd87d64a6a2a&quot;);
oidcConfiguration.setSecret(&quot;iGc8Q~wZ_~dffsdfsdfs&quot;);
oidcConfiguration.setDiscoveryURI(&quot;https://login.microsoftonline.com/sdfsdfs-2cb0-44dc-88cd-fdfs/v2.0/.well-known/openid-configuration&quot;);
oidcConfiguration.setUseNonce(true);
oidcConfiguration.addCustomParam(&quot;prompt&quot;, &quot;consent&quot;);
oidcClient = new OidcClient(oidcConfiguration);
/* oidcClient.setAuthorizationGenerator((webContext, sessionStore, userProfile) -&gt; {
userProfile.addRole(&quot;ConfiguratorOne&quot;);
return java.util.Optional.of(userProfile);
}
);*/
// REST authent with JWT for a token passed in the url as the token parameter
final List&lt;SignatureConfiguration&gt; signatures = new ArrayList&lt;&gt;();
signatures.add(new SecretSignatureConfiguration(JWT_SALT));
ParameterClient parameterClient = new ParameterClient(&quot;token&quot;, new JwtAuthenticator(signatures));
parameterClient.setSupportGetRequest(true);
parameterClient.setSupportPostRequest(false);
final Clients clients = new Clients(&quot;https://localhost:8443/myapplication/oidc/rest/sp/consumer&quot;, oidcClient);
final Config config = new Config(clients);
config.addAuthorizer(&quot;custom&quot;, new CustomAuthorizer());
return config;
}

CallbackFilter.java

@WebFilter(filterName = &quot;CallbackFilter&quot;, urlPatterns = {&quot;/oidc/rest/*&quot;, &quot;/oidc/rest&quot;})
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 = &quot;authenticated&quot;;
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(&quot;OIDC response received&quot; +userProfile.getUsername());
LOG.info(&quot;&quot; + 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);
}

答案1

得分: 0

我在pac4j文档中搜索并发现我忘记在OidcConfiguration对象中设置范围。

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

设置范围后,现在我能够在IDP发送的声明中获取角色。

英文:

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.

huangapple
  • 本文由 发表于 2023年6月1日 17:32:15
  • 转载请务必保留本文链接:https://go.coder-hub.com/76380493.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定