实现这一目标的一种方法:
- 按照此示例实施自定义端点
请注意,提供者无需注册即可正常工作standalone.xml
,我只是将 JAR 添加到 Keycloak Docker 映像中。
添加一个验证给定访问令牌、查找用户、获取用户会话并在响应中设置 cookie 的方法(为简洁起见,省略了大多数错误处理):
@GET
@Produces(MediaType.APPLICATION_JSON)
@Path("sso")
public Response sso(@Context final HttpRequest request) {
final HttpHeaders headers = request.getHttpHeaders();
final String authorization = headers.getHeaderString(HttpHeaders.AUTHORIZATION);
final String[] value = authorization.split(" ");
final String accessToken = value[1];
final AccessToken token = Tokens.getAccessToken(accessToken, keycloakSession);
if (token == null) {
throw new ErrorResponseException(Errors.INVALID_TOKEN, "Invalid access token", Status.UNAUTHORIZED);
}
final RealmModel realm = keycloakSession.getContext().getRealm();
final UriInfo uriInfo = keycloakSession.getContext().getUri();
final ClientConnection clientConnection = keycloakSession.getContext().getConnection();
final UserModel user = keycloakSession.users().getUserById(token.getSubject(), realm);
final UserSessionModel userSession = keycloakSession.sessions().getUserSession(realm, token.getSessionState());
AuthenticationManager.createLoginCookie(keycloakSession, realm, user, userSession, uriInfo, clientConnection);
return Response.noContent().build();
}
免责声明:我不完全确定这个实现并不意味着任何安全问题,但由于Tokens.getAccessToken(accessToken, keycloakSession)
访问令牌的完全验证,设置 cookie 应该只能使用有效的访问令牌。
对于 CORS,添加:
@OPTIONS
@Produces(MediaType.APPLICATION_JSON)
@Path("sso")
public Response preflight(@Context final HttpRequest request) {
return Cors.add(request, Response.ok("", MediaType.APPLICATION_JSON))
.auth()
.preflight()
.allowedMethods("GET", "OPTIONS")
.build();
}
并在sso()
:
return Cors.add(request, Response.ok("", MediaType.APPLICATION_JSON))
.auth()
.allowedMethods("GET")
.allowedOrigins(token)
.build();
我不确定的是为什么 Firefox 会预检GET
请求,因此有必要处理它。