我必须在Shiro中创建自定义领域,并且我必须使用带有"salt“的密码。
我使用的代码类似于:
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken)
throws AuthenticationException {
...
Admin admin = query.getByUsername(username);
String passwordSalted = admin.getPassword();
SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(username, passwordSalted, new SimpleByteSource(MY_PRIVATE_SALT), getName());
return info;
}
public Admin createAdmin(AuthenticationToken authenticationToken){
DefaultHashService hashService = new DefaultHashService();
hashService.setHashIterations(500000);
hashService.setHashAlgorithmName(Sha256Hash.ALGORITHM_NAME);
hashService.setPrivateSalt(new SimpleByteSource(MY_PRIVATE_SALT)); // Same salt as in shiro.ini, but NOT base64-encoded.
hashService.setGeneratePublicSalt(true);
DefaultPasswordService passwordService = new DefaultPasswordService();
passwordService.setHashService(hashService);
String encryptedPassword = passwordService.encryptPassword(authenticationToken.getCredentials());
Admin admin = new Admin();
String principal = authenticationToken.getPrincipal().toString();
admin.setUsername(principal);
admin.setPassword(encryptedPassword);
return admin;
}我使用"createAdmin“函数创建一个管理员,然后将其存储在数据库中,如下所示:
UsernamePasswordToken u = new UsernamePasswordToken("foo","qwerty") ;
Admin admin = createAdmin(u);
query.save(admin);保存的密码类似于:
$shiro1$SHA-256$50000$M7T93MZ65TCxXBsD7JFa9A==$gJcEf2oSKE/RKXifwYiJCaHU7X10ng1PxqL3AEMvmjE=
我不知道为什么它没有通过认证:
Factory<SecurityManager> factory =
new IniSecurityManagerFactory("classpath:shiro.ini");
SecurityManager securityManager = factory.getInstance();
SecurityUtils.setSecurityManager(securityManager);
AuthenticationToken authenticationToken = new UsernamePasswordToken("foo", "qwerty");
Subject usr = SecurityUtils.getSubject();
try {
securityManager.login(usr, authenticationToken);
} catch (Exception e) {
log.error("error");
}和我的shiro.ini:
[main]
customSecurityRealm=cl.fooproyect.CustomRealm已解决:
为了解决这个问题,我必须更改shiro.ini和createAdmin。我把责任交给shiro去制造盐。这个解决方案对我很有效。
shiro.ini中的更改
[main]
passwordService = org.apache.shiro.authc.credential.DefaultPasswordService
passwordMatcher = org.apache.shiro.authc.credential.PasswordMatcher
passwordMatcher.passwordService = $passwordService
customSecurityRealm=cl.doman.punto.vaadin.shiro.CustomRealm
customSecurityRealm.credentialsMatcher = $passwordMatcher
securityManager.realms = $customSecurityRealmcreateAdmin中的更改:
public Admin createAdmin(AuthenticationToken authenticationToken){
DefaultHashService hashService = new DefaultHashService();
DefaultPasswordService passwordService = new DefaultPasswordService();
String encryptedPassword = passwordService.encryptPassword(authenticationToken.getCredentials());
Admin admin = new Admin();
String principal = authenticationToken.getPrincipal().toString();
admin.setUsername(principal);
admin.setPassword(encryptedPassword);
return admin;
}发布于 2014-08-09 20:44:52
您需要确保您的领域使用与创建用户时相同的密码散列设置。
如果你使用spring,你可以用它们做bean,但是如果你没有使用类似的东西,你可以使用下面的想法来创建某种工厂,为每个需要的服务创建一个对象。
无论如何,下面是我们配置密码/散列/自定义域的方式。
首先创建密码服务:
@Configuration
public class SecurityConfiguration {
private static final String PRIVATE_SALT = "ourprivatesalt";
private PasswordService passwordService;
private PasswordMatcher credentialsMatcher = new PasswordAndSystemCredentialsMatcher();
private AuthenticatingSecurityManager securityManager;
@Bean
public PasswordService passwordService() {
if (passwordService == null) {
DefaultPasswordService defaultPasswordService = new DefaultPasswordService();
passwordService = defaultPasswordService;
DefaultHashService defaultHashService = (DefaultHashService) defaultPasswordService.getHashService();
defaultHashService.setPrivateSalt(new SimpleByteSource(PRIVATE_SALT));
}
return passwordService;
}
@Bean
public CredentialsMatcher credentialsMatcher() {
credentialsMatcher.setPasswordService(passwordService());
return credentialsMatcher;
}然后是我们的自定义领域:
@Service
public class OurRealmImpl extends AuthorizingRealm {
@Autowired
private CredentialsMatcher credentialsMatcher;
@PostConstruct
private void configure() {
setCredentialsMatcher(credentialsMatcher);
}查看您的代码,我认为缺少的是您没有在自定义领域中更改凭据匹配器。
https://stackoverflow.com/questions/25215274
复制相似问题