WS-security (usernametoken) для CXF - возможны ли зашифрованные пароли?

Я пытаюсь собраться вместе с реализацией WS-безопасности CXF (usernametoken). Я сделал все, как сказано на http://cxf.apache.org/docs/ws-security.html. Мой PasswordCallbackHandler, кажется, работает, но то, что беспокоит меня, является частью:

    if (pc.getIdentifier().equals("joe")) {
        // set the password on the callback. This will be compared to the
        // password which was sent from the client.
        pc.setPassword("password");
    }

как сказал

Обратите внимание, что вплоть до CXF 2.3.x включительно проверка пароля в особом случае обычного текстового пароля (или любого другого, пока неизвестного типа пароля) делегируется классу обратного вызова, см. Org.apache.ws.security.processor.UsernameTokenProcessor#handleUsernameToken(), метод javadoc проекта WSS4J. В этом случае ServerPasswordCallback должен выглядеть примерно так:

так что до cxf 2.3.x было сделано так

   if (pc.getIdentifer().equals("joe") {
       if (!pc.getPassword().equals("password")) {
            throw new IOException("wrong password");
       }
    }

Моя проблема: я не хочу pc.setPassword("plainTextPassword"), поскольку я хочу сохранить его в любом ресурсе. Этот дизайн до 2.3.x позволил бы мне сделать это, так как я мог зашифровать его вручную. Есть ли способы установить зашифрованный пароль в обратном вызове или выполнить аутентификацию на основе имени пользователя для сохраненных зашифрованных паролей?

Я использую cxf 2.5.x

2 ответа

Ответ (который я пробовал) находится на этой странице блога:

http://coheigea.blogspot.com/2011/06/custom-token-validation-in-apache-cxf.html

Суть в том, чтобы создать подкласс org.apache.ws.security.validate.UsernameTokenValidator и переопределить метод verifyPlaintextPassword. В этом методе передается UsernameToken (который предоставляет getName и getPassword). Бросьте исключение, если они не действительны.

Чтобы установить пользовательский валидатор в конфигурации пружины, добавьте, например,

  <jaxws:properties>
    <entry key="ws-security.ut.validator">
        <bean class="com.example.webservice.MyCustomUsernameTokenValidator" />
    </entry>
  </jaxws:properties>

в .

Обработчики обратного вызова предназначены для предоставления пароля в виде открытого текста или проверки пароля дайджеста, если известен пароль в виде открытого текста.

Но если вы не знаете открытый текст, т.е. его односторонний хэширование, то интерфейс обратного вызова не подходит, и вы должны создать класс, который реализует интерфейс Validator.

Вот мой пример реализации этого интерфейса, в котором используется репозиторий JPA, в котором пароль уже хранится в виде хэша BCrypt.

Используйте с ws-security.ut.validator собственность задокументирована здесь

т.е. как свойство CXF<entry key="ws-security.ut.validator" value-ref="com.package.CustomUsernameTokenValidator" />

public class CustomUsernameTokenValidator implements Validator {
    @Autowired
    ProfileRepository profileRepository;
    @Override
    public Credential validate(Credential credential, RequestData requestData) throws WSSecurityException {
        Profile profile = profileRepository.findByName(credential.getUsernametoken().getName());
        if (profile != null) {
            if (BCrypt.checkpw(credential.getUsernametoken().getPassword(), profile.getPassword())) {
                return credential;
            }
        }
        throw new WSSecurityException(WSSecurityException.ErrorCode.FAILED_AUTHENTICATION);     
    }
}
Другие вопросы по тегам