2012-01-19 2 views
7

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

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"); 
     } 
    } 

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

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

+0

Здравствуйте! Насколько мне известно, WSS4J выполняет всю работу по шифрованию для вас. Если вы хотите зашифровать пароль еще раз в обратном вызове, почему в нем не будет использоваться собственный шифр? – Dmitry

+0

Я хотел сохранить зашифрованный пароль (т.по ша), а затем набирать входящий с сохраненным). Точка должна была хранить _encrypted_ пароль – Jan

+0

Вопрос имеет отношение ко мне, потому что я (программное обеспечение) не знаю фактического пароля пользователя. У меня только односторонний (склеп) пароль, поэтому я не могу предоставить фактический пароль для обратного вызова WSS4J, но я могу проверить, действительно ли предоставленный пароль. Я уверен, что это можно сделать как-то ... – dmansfield

ответ

6

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

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

Суть в том, чтобы создать подкласс орг .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> 

< в JAXWS: конечная точка/>.

2

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

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

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

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

т.е. как свойство 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);  
    } 
}