我試圖啓用基於角色的訪問控制,我已設置使用底池,球衣和CDI的休息終點。我初始化servlet部署如下:Undertow servlet處理程序丟失已經通過keycloak管理的身份驗證和有效的SecurityContext
DeploymentInfo servletBuilder = Servlets.deployment()
.setClassLoader(Main.class.getClassLoader())
.setContextPath("/rest")
.setDeploymentName("sv.war")
.addListeners(listener(Listener.class))
.setLoginConfig(new LoginConfig("KEYCLOAK", "some-realm"))
.setAuthorizationManager(auth) // my dummy for testing
.addServlets(servlet("jerseyServlet", ServletContainer.class)
.setLoadOnStartup(1)
.addInitParam("javax.ws.rs.Application", SystemViewApplication.class.getName())
.addMapping("/api/*"));
我啓用kecloak認證基於this example code。
所以,我的服務器啓動爲:
DeploymentManager manager = Servlets.defaultContainer().addDeployment(servletBuilder);
manager.deploy();
PathHandler path = Handlers.path(Handlers.resource(staticResources).setDirectoryListingEnabled(false).setWelcomeFiles("index.html"))
.addPrefixPath("/rest", manager.start());
Undertow server = Undertow.builder()
.addHttpListener(8087, "localhost")
.setHandler(sessionHandling(addSecurity(exchange -> {
final SecurityContext context = exchange.getSecurityContext();
if (!context.isAuthenticated()) {
exchange.endExchange();
return;
}
log.info("Authenticated: {} {} {}", context.getMechanismName(), context.getAuthenticatedAccount().getPrincipal().getName(), context.getAuthenticatedAccount().getRoles());
// propagate the request
path.handleRequest(exchange);
})))
.build();
server.start();
如果這兩種方法sessionHandling()
和addSecurity()
從例如舉起我上面鏈接。
驗證有效,我強制登錄,並且Authenticated: ..
記錄行用正確的詳細信息打印出來。但是,一旦它遇到了servlet處理,安全上下文(和帳戶)就會丟失。我跟蹤了這個電話,我可以看到在路上的某個時刻,它被替換爲全新的SecurityContext
,它有一個空賬戶。
現在我的問題 - 是否有一些身份驗證機制,我錯過了將在keycloak身份驗證之後傳播狀態,或者我可以只修復上游代碼,並且在SecurityContext
中,如果傳入的上下文已經正確驗證,該狀態並繼續前進? (後者看起來不正確,我猜這是因爲這可能是servlet部署的不同身份驗證?)如果是這樣,是否有任何方法連接servlet部署以查看keycloak身份驗證已經發生?