我有这个shiro.ini:
[main]
ds = org.apache.shiro.jndi.JndiObjectFactory
ds.requiredType = javax.sql.DataSource
ds.resourceName = java:/comp/env/jdbc/myDS
# JDBC realm config
jdbcRealm = org.apache.shiro.realm.jdbc.JdbcRealm
jdbcRealm.permissionsLookupEnabled = true
jdbcRealm.authenticationQuery = "SELECT password FROM user WHERE username = ?"
jdbcRealm.dataSource = $ds
credentialsMatcher = org.apache.shiro.authc.credential.Sha256CredentialsMatcher
# base64 encoding, not hex in this example:
credentialsMatcher.storedCredentialsHexEncoded = false
credentialsMatcher.hashIterations = 1024
jdbcRealm.credentialsMatcher = $credentialsMatcher
[urls]
/logout = logout
/** = authcBasic
我在doGetAuthenticationInfo中重新编写JndiRealm。当shiro尝试在getPasswordForUser方法中执行我的authenticationQuery时,我得到一个例外。这些是执行选择的行:
ps = conn.prepareStatement(authenticationQuery);
ps.setString(1, username);
我的atuthenticationQuery是“SELECT password FROM user WHERE username =?”所以尝试访问位置1是无效的,因为它从位置0开始。这是来自apache shiro的JndiRealm上的错误还是我写错了我的SQL?
答案 0 :(得分:0)
看起来你有一个领域的简单模拟实现。
要登录工作,您需要两个步骤:
看起来你只创建了第一步,但是你只是在return语句中给出了密码。
Shiro将散列用户输入的密码。您应该在数据库中的某处存储相同的哈希。在doGetAuthenticationInfo中,您应该根据输入的用户名进行查找并检索哈希值(从数据库,磁盘或您喜欢的任何内容),这是您应该放在SimpleAuthenticationInfo对象中并返回,shiro将执行用户密码哈希和比较。
对于第二步,重写方法doGetAuthorizationInfo。您可以让它返回包含一组权限的SimpleAuthorixationInfo实例,最简单的是“*”,当它可以访问所有内容时。
创建这样的方法可以简单如下:
@Override
public AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
//here you can create custom permissions based on the principal
//that has been authenticated using your own logic
info.addStringPermission("*");
return info;
}