英文:
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
<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);
}
答案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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论