2

現在、Spring セキュリティを使用している Spring MVC アプリのキークロークの手順を探しています。

Sitewhere でkeycloakを使用したかったのです。

4

1 に答える 1

1

keycloakのドキュメントを完全に読んでいれば、これはとても簡単だと思います:)。Sitewhere でキークロークに移行する際に従った手順は次のとおりです。

  1. spring-security のkeycloak doc に記載されている手順に従ってください
  2. アダプターのインストールに記載されているように、依存関係を sitewhere-core および sitewhere-web pom.xml に追加します。
  3. また、keycloak スプリング アダプターには jboss-logging のハードコード依存関係があるため、sitewhere-web の pom.xml に jboss-logging 依存関係を追加します。
  4. api のサンプルに従って、web と api の両方で keycloak を使用できるように applicationcontext.xml を変更します。

    <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" />
    

  5. 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();
    

    }

  6. 認証をキークロークに移行したため、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;}
    
  7. keycloak 内のユーザーには、sitewhere により固有のそれぞれの役割があることを確認してください。

  8. 認証目的でキークロークにリダイレクトするようにホームページを変更します。以下は、リダイレクトのサンプルです。

        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);
    }
    
于 2015-10-20T11:25:54.957 に答える