shiro配置文件:shiro.ini
[main] credentialsMatcher=com.github.zhangkaitao.shiro.chapter6.credentials.RetryLimitHashedCredentialsMatcher credentialsMatcher.hashAlgorithmName=md5 credentialsMatcher.hashIterations=2 credentialsMatcher.storedCredentialsHexEncoded=true userRealm=com.github.zhangkaitao.shiro.chapter6.realm.UserRealm userRealm.credentialsMatcher=$credentialsMatcher securityManager.realms=$userRealm
自定义验证匹配器RetryLimitHashedCredentialsMatcher
package com.github.zhangkaitao.shiro.chapter6.credentials; import net.sf.ehcache.CacheManager; import net.sf.ehcache.Ehcache; import net.sf.ehcache.Element; import org.apache.shiro.authc.AuthenticationInfo; import org.apache.shiro.authc.AuthenticationToken; import org.apache.shiro.authc.ExcessiveAttemptsException; import org.apache.shiro.authc.credential.HashedCredentialsMatcher; import java.util.concurrent.atomic.AtomicInteger; /** * <p>User: Zhang Kaitao * <p>Date: 14-1-28 * <p>Version: 1.0 */ public class RetryLimitHashedCredentialsMatcher extends HashedCredentialsMatcher { private Ehcache passwordRetryCache; public RetryLimitHashedCredentialsMatcher() { CacheManager cacheManager = CacheManager.newInstance(CacheManager.class.getClassLoader().getResource("ehcache.xml")); passwordRetryCache = cacheManager.getCache("passwordRetryCache"); } @Override public boolean doCredentialsMatch(AuthenticationToken token, AuthenticationInfo info) { //缓存处理,有则在缓存中取,无则放入缓存中,key:用户名 value:登录次数 String username = (String)token.getPrincipal(); //retry count + 1 Element element = passwordRetryCache.get(username); if(element == null) { element = new Element(username , new AtomicInteger(0)); passwordRetryCache.put(element); } AtomicInteger retryCount = (AtomicInteger)element.getObjectValue(); //登录次数大于5次则抛验证次数超量异常 if(retryCount.incrementAndGet() > 5) { //if retry count > 5 throw throw new ExcessiveAttemptsException(); } //调用父类校验加密密码 boolean matches = super.doCredentialsMatch(token, info); if(matches) { //clear retry count passwordRetryCache.remove(username); } return matches; } }
自定义userRealm
package com.github.zhangkaitao.shiro.chapter6.realm; import com.github.zhangkaitao.shiro.chapter6.service.UserService; import com.github.zhangkaitao.shiro.chapter6.service.UserServiceImpl; import com.github.zhangkaitao.shiro.chapter6.entity.User; import org.apache.shiro.authc.*; import org.apache.shiro.authz.AuthorizationInfo; import org.apache.shiro.authz.SimpleAuthorizationInfo; import org.apache.shiro.realm.AuthorizingRealm; import org.apache.shiro.subject.PrincipalCollection; import org.apache.shiro.util.ByteSource; /** * <p>User: Zhang Kaitao * <p>Date: 14-1-28 * <p>Version: 1.0 */ public class UserRealm extends AuthorizingRealm { private UserService userService = new UserServiceImpl(); @Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) { String username = (String)principals.getPrimaryPrincipal(); SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo(); authorizationInfo.setRoles(userService.findRoles(username)); authorizationInfo.setStringPermissions(userService.findPermissions(username)); return authorizationInfo; } @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException { String username = (String)token.getPrincipal(); //根据用户传入的用户名查询用户 User user = userService.findByUsername(username); if(user == null) { throw new UnknownAccountException();//没找到帐号 } if(Boolean.TRUE.equals(user.getLocked())) { throw new LockedAccountException(); //帐号锁定 } //查到的正确用户封装为SimpleAuthenticationInfo //交给AuthenticatingRealm使用CredentialsMatcher进行密码匹配,如果觉得人家的不好可以自定义实现 SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo( user.getUsername(), //用户名 user.getPassword(), //密码 ByteSource.Util.bytes(user.getCredentialsSalt()),//salt=username+salt getName() //realm name ); return authenticationInfo; } }
缓存配置
<?xml version="1.0" encoding="UTF-8"?> <ehcache name="es"> <diskStore path="java.io.tmpdir"/> <!-- 登录记录缓存 锁定10分钟 --> <cache name="passwordRetryCache" maxEntriesLocalHeap="2000" eternal="false" timeToIdleSeconds="3600" timeToLiveSeconds="0" overflowToDisk="false" statistics="true"> </cache> </ehcache>
注意:
以上配置了验证信息的加密算法,生成用户存储用户时要保证使用相同的加密手段
/** * 创建用户 * @param user */ public User createUser(User user) { //加密密码 passwordHelper.encryptPassword(user); return userDao.createUser(user); }
public class PasswordHelper { private RandomNumberGenerator randomNumberGenerator = new SecureRandomNumberGenerator(); private String algorithmName = "md5"; private final int hashIterations = 2; public void encryptPassword(User user) { user.setSalt(randomNumberGenerator.nextBytes().toHex()); String newPassword = new SimpleHash( algorithmName, user.getPassword(), ByteSource.Util.bytes(user.getCredentialsSalt()), hashIterations).toHex(); user.setPassword(newPassword); } }
相关推荐
总结来说,这个`FORM`身份认证实例展示了如何通过用户登录表单验证用户身份,并根据用户的角色分配相应的访问权限。`Login.aspx`处理登录过程,`Web.config`设置认证和授权策略,而其他`.cs`和`.designer.cs`文件则...
通过上面的代码,我们可以实现一个基于 Token 的身份认证实例,使用 JwtSecurityTokenHandler 来生成和验证 Token,从而确保身份认证的安全性。 在 ASP.NET Core 中实现一个 Token base 的身份认证实例可以使用微软...
在这个实例中,我们将深入探讨如何在ASP.NET中设置和使用Forms身份验证。 首先,我们需要在Web.config配置文件中定义身份验证模式为"Forms"。这可以通过以下XML代码完成: ```xml ~/Login.aspx" defaultUrl=...
JAVA中的Token基于Token的身份验证实例 本文档主要介绍了JAVA中的Token基于Token的身份验证实例,具有很好的参考价值。本文将详细介绍基于Token的身份验证方法,并与传统的身份验证方法进行比较。 一、传统身份...
**基于Forms的身份验证是Web应用程序中常用的一种安全机制,它主要用于确认用户的身份并控制对受保护资源的访问。本示例源代码提供了实现这一机制的基本步骤。** 在ASP.NET中,Forms身份验证允许用户通过输入用户名...
TOP应用实例,包括身份验证,这是一个war包,直接拷贝到Tomcat的webapps目录下即可运行。
在ASP.NET中,基于表单的身份验证(Form-Based Authentication)是一种常见的用户认证方式,它允许开发者创建自定义登录页面来验证用户凭证,而不是依赖于服务器的默认机制。这种验证方式非常适合那些需要自定义用户...
需要注意的是,这种方法虽然解决了在WinForm应用中验证Moss的身份认证问题,但它存在一些潜在的安全隐患。首先,明文传递用户名和密码并不安全,尤其是在代码中硬编码。其次,使用COM组件可能会引入版本兼容性问题。...
2. **SQL Server和Windows混合身份验证模式**:这种模式允许用户使用SQL Server自身的登录名进行认证,同时也支持Windows认证账户。这种方式提供了更大的灵活性,但同时也增加了安全管理的复杂性。 #### 二、更改...
身份验证过程中,用户的合法性验证是通过session提交数据来完成的。在无状态的HTTP协议中,服务端无法识别每个独立的用户,因此,PHP通过会话控制提供了一种机制,即为每个用户创建一个唯一的会话(session),通过...
该“NACOS身份认证绕过漏洞批量检测poc”是一个Proof of Concept(概念验证)文件,用于验证这个安全漏洞是否存在。POC文件通常包含一段代码或者脚本,开发者或安全研究人员可以使用这些代码来测试特定系统是否易受...
谷歌身份验证器使用时间同步的哈希消息认证码(Time-Based One-Time Password, TOTP)算法。TOTP基于当前时间生成一个六位或更多位的动态密码,通常每30秒更新一次。这个过程涉及到密钥的生成和验证。 1. **密钥...
WCF实例(基于X.509证书的身份验证)
SQLSERVER身份验证登录不上 SQLSERVER2005 解决 Windows 身份验证和 SQLSERVER 身份验证登录不上的问题是一个常见的问题。正如标题所示,本文将讨论两种身份验证登录不上的问题及其解决方法。 一、Windows 身份...
身份认证技术作为信息安全的重要组成部分,它通过验证用户身份来确保数据访问的合法性。 在身份认证技术中,EKE协议(Encrypted Key Exchange Protocol)是一种重要的密钥交换协议,它特别适用于弱口令条件下的安全...
Windows身份验证模式则仅支持使用Windows认证。 **步骤6:数据文件存储位置** - 设置数据文件的存储位置,通常建议将其放在非系统盘上,以提高性能和可靠性。 - 可以指定默认的MDF、LDF文件的位置以及日志文件的...