使用SHA256密码配置Apache Shiro for MySQL

时间:2014-08-01 01:49:50

标签: shiro

我正在努力收集必要的信息,以实现我的目标。我的目标很简单,利用Shiro进行身份验证和授权。我希望在Java Web应用程序上下文中部署shiro。我希望用户能够登录并检查MySQL数据库的凭据。我想为密码实现SHA256哈希。我并不喜欢,所以我使用传统的JSP和Servlet。

我正在使用的技术:Apache Tomcat 7,Apache Shiro,MySQL,Apache Web Server

我在这里走在正确的轨道上吗?


/WEB-INF/shiro.ini

[main]
# Using my JNDI resource for JDBC
dataSource = org.apache.shiro.jndi.JndiObjectFactory
dataSource.resourceName = jdbc/myResource
dataSource.resourceRef = true
jdbcRealm = org.apache.shiro.realm.jdbc.JdbcRealm
jdbcRealm.dataSource = $dataSource

# Using Pass Thru security filter so I can manage login.
authc = org.apache.shiro.web.filter.authc.PassThruAuthenticationFilter
authc.loginUrl = /login
authc.successUrl = /my-account

# Use default service and password matcher
passwordService = org.apache.shiro.authc.credential.DefaultPasswordService
passwordMatcher = org.apache.shiro.authc.credential.PasswordMatcher
passwordMatcher.passwordService = $passwordService

#Realms section
# Finally, set the matcher on a realm that requires password matching for account authentication: 
# myRealm.credentialsMatcher = $passwordMatcher 
# ???

[users]

[roles]


[urls]
/login = authc
/logout = logout

问题1:在我的“#Use service service and password matcher”部分下,这是配置Shiro与SHA256进行密码比较的正确方法吗?

问题2:在我的“#Realms部分”部分下,我不明白该怎么做。您能否建议CredentialsMatcher代码应该是什么样子?

关于问题2,我注意到CredentialsMatcher interface文档,建议使用HashedCrendentialsMatcher进行比较。我应该创建一个使用HashedCredentialsMatcher的新java类吗?然后我会在shiro.ini文件中引用该类作为我的“领域”?


新帐户注册

创建新用户时,我想加密密码。我选择使用Shiro框架提供的加密工具。我将使用DefaultPasswordService对象实例来加密我的用户密码。结果值存储在数据库中。

String rawPassword = "secret";
DefaultPasswordService passwordService = new DefaultPasswordService();
String encryptedPassword = passwordService.encryptPassword(rawPassword);
String hash = passwordService.hashPassword(rawPassword).toString();

//Create the user
User user = new User();
user.setUsername(username)
user.setEncryptedPassword(encryptedPassword);
user.setHash(hash);

//Save to Database
userDAO.save(user);

//Log the user in immediately after new account created.
try {
    UsernamePasswordToken userToken = new UsernamePasswordToken(username, rawPassword);
    SecurityUtils.getSubject().login(userToken);
} catch (UnknownAccountException uae) {
    LogMe.s(this.getClass().getName(), "Log error specific message here...", uae);
} catch (IncorrectCredentialsException ice) {
    LogMe.s(this.getClass().getName(), "Log error specific message here...", ice);
} catch (LockedAccountException lae) {
    LogMe.s(this.getClass().getName(), "Log error specific message here...", lae);
} catch (ExcessiveAttemptsException eae) {
    LogMe.s(this.getClass().getName(), "Log error specific message here...", eae);
} catch (AuthenticationException ae) {
    LogMe.s(this.getClass().getName(), "Log error specific message here...", ae);
}catch (Exception ex) {
    LogMe.s(this.getClass().getName(), "Log error specific message here...", ex);
}

问题3:就我的“新帐户注册”逻辑而言,这是一种可接受的方法吗?建议?问另一种方式,我正确配置?

问题4:在MySQL中存储哈希值时,是否可以使用hashPassword()将其转换为字符串?哈希值字段是否有建议的长度:例如VARCHAR(15)?


用户登录

我选择在登录过程中手动验证用户身份。我可以从Servlet中检索POST中的用户名/密码。我最终将建立AJAX登录机制,这就是我选择这种方法的原因。这是我难倒的地方。以下是两个片段。第一个是提交给我的servlet的html表单。第二个片段是执行身份验证的方法。

/登录

<form name="loginform" action="login.do" method="post">
    <p>Username</p> 
    <input type="text" name="username" />
    <p>Password</p>        
    <input type="password" name="password" />
    <input type="submit" value="Login" />
</form>

登录方式

//Getters and Setters omitted for username, rawPassword.

private void login() {
    if (!SecurityUtils.getSubject().isAuthenticated()) {
        String fallbackUrl = "/user-account-default-page";
        try {
            UsernamePasswordToken userToken = new UsernamePasswordToken(username, rawPassword);
            SecurityUtils.getSubject().login(userToken);

            //Take advantage of the auto redirect to the page user wanted. Or default to the fallbackUrl
            WebUtils.redirectToSavedRequest(request, response, fallbackUrl);
        } catch (UnknownAccountException uae) {
            LogMe.s(this.getClass().getName(), "Log error specific message here...", uae);
        } catch (IncorrectCredentialsException ice) {
            LogMe.s(this.getClass().getName(), "Log error specific message here...", ice);
        } catch (LockedAccountException lae) {
            LogMe.s(this.getClass().getName(), "Log error specific message here...", lae);
        } catch (ExcessiveAttemptsException eae) {
            LogMe.s(this.getClass().getName(), "Log error specific message here...", eae);
        } catch (AuthenticationException ae) {
            LogMe.s(this.getClass().getName(), "Log error specific message here...", ae);
        }catch (Exception ex) {
            LogMe.s(this.getClass().getName(), "Log error specific message here...", ex);
        }
    }
}

/注销

由于shiro.ini文件中的代码片段,Shiro会注销用户?通过将URL“/ logout”设置为logout,Shrio会将用户注销。它是否正确?

# Section of the shiro.ini file
[urls]
/logout = logout

感谢您提供的所有见解。我希望这个问题不是霸道,也许将来会帮助别人。另请注意,我最初在shiro forums上提出了这个问题。

0 个答案:

没有答案