我的web服务使用apache shiro总是返回未经授权

时间:2014-08-06 17:38:17

标签: web-services security shiro unauthorized

我有这个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?

1 个答案:

答案 0 :(得分:0)

看起来你有一个领域的简单模拟实现。

要登录工作,您需要两个步骤:

  1. 身份验证(用户名/密码正确)
  2. 授权(允许用户做什么)
  3. 看起来你只创建了第一步,但是你只是在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;
    }