为使用 spring 安全性的应用程序迁移到 keycloak
Migrating to keycloak for an app that uses spring security
我正在寻找为当前使用 spring 安全性的 Spring MVC 应用程序隐藏密钥的步骤。
我想在 Sitewhere 中使用 keycloak。
如果我完整阅读了 keycloak 的文档,我想这会很简单:)。这是我在 Sitewhere 中迁移到 keycloak 时遵循的步骤。
- 按照 spring-security
的 keycloak 文档中给出的步骤进行操作
- 将依赖项添加到 sitewhere-core 和 sitewhere-web pom.xml,如 adapter installation
中所述
- 还要在 sitewhere-web 的 pom.xml 中添加 jboss-logging 依赖项,因为 keycloak spring 适配器具有 jboss-logging 的硬编码依赖项。
修改 applicationcontext.xml 以便它可以在网络和 api 中使用 keycloak,遵循 api
的示例
<sec:http pattern="/api/**" entry-point-ref="keycloakAuthenticationEntryPoint">
<sec:custom-filter ref="keycloakPreAuthActionsFilter" before="LOGOUT_FILTER" />
<sec:custom-filter ref="keycloakAuthenticationProcessingFilter" before="FORM_LOGIN_FILTER" />
修改LoginManager.java如下
public static IUser getCurrentlyLoggedInUser() throws SiteWhereException {
Authentication KeyCloakAuth = SecurityContextHolder.getContext().getAuthentication();
if (KeyCloakAuth == null) {
throw new SiteWhereSystemException(ErrorCode.NotLoggedIn, ErrorLevel.ERROR,
HttpServletResponse.SC_FORBIDDEN);
}
KeycloakAccount keyAccount = ((KeycloakAuthenticationToken) KeyCloakAuth).getAccount();
String username = keyAccount.getKeycloakSecurityContext().getIdToken().getPreferredUsername();
String password = "";
IUser user = SiteWhere.getServer().getUserManagement().authenticate(username, password);
List<IGrantedAuthority> auths =
SiteWhere.getServer().getUserManagement().getGrantedAuthorities(user.getUsername());
SitewhereUserDetails details = new SitewhereUserDetails(user, auths);
Authentication auth = new SitewhereAuthentication(details, password);
if (!(auth instanceof SitewhereAuthentication)) {
throw new SiteWhereException("Authentication was not of expected type: "
+ SitewhereAuthentication.class.getName() + " found " + auth.getClass().getName()
+ " instead.");
}
return (IUser) ((SitewhereAuthentication) auth).getPrincipal();
}
从那以后,我们已经将我们的身份验证迁移到 keycloak 并且因为我们不会在 siter 中获取用户凭据,所以最好将 IUserManagement 的身份验证方法中与密码验证相关的代码作废。以下是来自 MongoUserManagement.java
的示例
public IUser authenticate(String username, String password) throws SiteWhereException {
if (password == null) {
throw new SiteWhereSystemException(ErrorCode.InvalidPassword, ErrorLevel.ERROR,
HttpServletResponse.SC_BAD_REQUEST);
}
DBObject userObj = assertUser(username);
String inPassword = SiteWherePersistence.encodePassoword(password);
User match = MongoUser.fromDBObject(userObj);
//nullify authentication since we are using keycloak
/*if (!match.getHashedPassword().equals(inPassword)) {
throw new SiteWhereSystemException(ErrorCode.InvalidPassword, ErrorLevel.ERROR,
HttpServletResponse.SC_UNAUTHORIZED);
}*/
// Update last login date.
match.setLastLogin(new Date());
DBObject updated = MongoUser.toDBObject(match);
DBCollection users = getMongoClient().getUsersCollection();
BasicDBObject query = new BasicDBObject(MongoUser.PROP_USERNAME, username);
MongoPersistence.update(users, query, updated);
return match;}
确保您在 keycloak 中拥有更特定于 sitewhere 的用户各自的角色。
更改您的主页,以便它重定向到 keycloak 以进行身份验证。以下是重定向示例:
Tracer.start(TracerCategory.AdminUserInterface, "login", LOGGER);
try {
Map<String, Object> data = new HashMap<String, Object>();
data.put("version", VersionHelper.getVersion());
String keycloakConfig = environment.getProperty("AUTHSERVER_REDIRECTION_URL");
if (SiteWhere.getServer().getLifecycleStatus() == LifecycleStatus.Started) {
return new ModelAndView("redirect:"+keycloakConfig);
} else {
ServerStartupException failure = SiteWhere.getServer().getServerStartupError();
data.put("subsystem", failure.getDescription());
data.put("component", failure.getComponent().getLifecycleError().getMessage());
return new ModelAndView("noserver", data);
}
} finally {
Tracer.stop(LOGGER);
}
我正在寻找为当前使用 spring 安全性的 Spring MVC 应用程序隐藏密钥的步骤。
我想在 Sitewhere 中使用 keycloak。
如果我完整阅读了 keycloak 的文档,我想这会很简单:)。这是我在 Sitewhere 中迁移到 keycloak 时遵循的步骤。
- 按照 spring-security 的 keycloak 文档中给出的步骤进行操作
- 将依赖项添加到 sitewhere-core 和 sitewhere-web pom.xml,如 adapter installation 中所述
- 还要在 sitewhere-web 的 pom.xml 中添加 jboss-logging 依赖项,因为 keycloak spring 适配器具有 jboss-logging 的硬编码依赖项。
修改 applicationcontext.xml 以便它可以在网络和 api 中使用 keycloak,遵循 api
的示例<sec:http pattern="/api/**" entry-point-ref="keycloakAuthenticationEntryPoint"> <sec:custom-filter ref="keycloakPreAuthActionsFilter" before="LOGOUT_FILTER" /> <sec:custom-filter ref="keycloakAuthenticationProcessingFilter" before="FORM_LOGIN_FILTER" />
修改LoginManager.java如下
public static IUser getCurrentlyLoggedInUser() throws SiteWhereException { Authentication KeyCloakAuth = SecurityContextHolder.getContext().getAuthentication(); if (KeyCloakAuth == null) { throw new SiteWhereSystemException(ErrorCode.NotLoggedIn, ErrorLevel.ERROR, HttpServletResponse.SC_FORBIDDEN); } KeycloakAccount keyAccount = ((KeycloakAuthenticationToken) KeyCloakAuth).getAccount(); String username = keyAccount.getKeycloakSecurityContext().getIdToken().getPreferredUsername(); String password = ""; IUser user = SiteWhere.getServer().getUserManagement().authenticate(username, password); List<IGrantedAuthority> auths = SiteWhere.getServer().getUserManagement().getGrantedAuthorities(user.getUsername()); SitewhereUserDetails details = new SitewhereUserDetails(user, auths); Authentication auth = new SitewhereAuthentication(details, password); if (!(auth instanceof SitewhereAuthentication)) { throw new SiteWhereException("Authentication was not of expected type: " + SitewhereAuthentication.class.getName() + " found " + auth.getClass().getName() + " instead."); } return (IUser) ((SitewhereAuthentication) auth).getPrincipal();
}
从那以后,我们已经将我们的身份验证迁移到 keycloak 并且因为我们不会在 siter 中获取用户凭据,所以最好将 IUserManagement 的身份验证方法中与密码验证相关的代码作废。以下是来自 MongoUserManagement.java
的示例public IUser authenticate(String username, String password) throws SiteWhereException { if (password == null) { throw new SiteWhereSystemException(ErrorCode.InvalidPassword, ErrorLevel.ERROR, HttpServletResponse.SC_BAD_REQUEST); } DBObject userObj = assertUser(username); String inPassword = SiteWherePersistence.encodePassoword(password); User match = MongoUser.fromDBObject(userObj); //nullify authentication since we are using keycloak /*if (!match.getHashedPassword().equals(inPassword)) { throw new SiteWhereSystemException(ErrorCode.InvalidPassword, ErrorLevel.ERROR, HttpServletResponse.SC_UNAUTHORIZED); }*/ // Update last login date. match.setLastLogin(new Date()); DBObject updated = MongoUser.toDBObject(match); DBCollection users = getMongoClient().getUsersCollection(); BasicDBObject query = new BasicDBObject(MongoUser.PROP_USERNAME, username); MongoPersistence.update(users, query, updated); return match;}
确保您在 keycloak 中拥有更特定于 sitewhere 的用户各自的角色。
更改您的主页,以便它重定向到 keycloak 以进行身份验证。以下是重定向示例:
Tracer.start(TracerCategory.AdminUserInterface, "login", LOGGER); try { Map<String, Object> data = new HashMap<String, Object>(); data.put("version", VersionHelper.getVersion()); String keycloakConfig = environment.getProperty("AUTHSERVER_REDIRECTION_URL"); if (SiteWhere.getServer().getLifecycleStatus() == LifecycleStatus.Started) { return new ModelAndView("redirect:"+keycloakConfig); } else { ServerStartupException failure = SiteWhere.getServer().getServerStartupError(); data.put("subsystem", failure.getDescription()); data.put("component", failure.getComponent().getLifecycleError().getMessage()); return new ModelAndView("noserver", data); } } finally { Tracer.stop(LOGGER); }