您的位置:首页 > 编程语言 > Java开发

spring集成shiro实现登录认证自定义验证功能(认证采用国密SM4算法)

2017-12-20 11:56 1236 查看
        公司在建项目采用的开发框架为spring+springMvc+hibernate,安全框架采用的是shiro,安全认证沿用了shiro自带的HashedCredentialsMatcher,现客户(国企)要求用户密码必须采用国密SM4算法进行加密,因此需对安全认证模块进行改造。

SM4加密JAVA版可参考:http://blog.csdn.net/lemon_tree12138/article/details/42678723

1、新建一个自定义的适用于SMA4安全认证匹配类:

public class SM4CredentialsMatcher extends SimpleCredentialsMatcher {

protected UserService userService;

@Override
public boolean doCredentialsMatch(AuthenticationToken authcToken, AuthenticationInfo info) {
UsernamePasswordToken token = (UsernamePasswordToken) authcToken;
User user = userService.findByLoginName(token.getUsername());
String salt = "";
if (user != null) {
if ("disabled".equals(user.getStatus())) {
throw new DisabledAccountException();
}

salt = user.getSalt();
}
Object tokenCredentials = SM4Util.encrypt(String.valueOf(token.getPassword()), salt);
Object accountCredentials = getCredentials(info);
// 将密码加密与系统加密后的密码校验,内容一致就返回true,不一致就返回false
return equals(tokenCredentials, accountCredentials);
}

public void setUserService(UserService userService) {
this.userService = userService;
}

}

2、修改自定义Realm类,重写两个方法:initCredentialsMatcher和assertCredentialsMatch

public class ShiroDbRealm extends AuthorizingRealm {

protected UserService userService;

protected RoleService roleService;

protected SM4CredentialsMatcher sm4CredentialsMatcher;

/**
* 认证回调函数,登录时调用.
*/
@Override
protected AuthenticationInfo doGetAuthenticationInfo(
AuthenticationToken authcToken) throws AuthenticationException {
UsernamePasswordToken token = (UsernamePasswordToken) authcToken;
User user = userService.findByLoginName(token.getUsername());
if (user != null) {
if ("disabled".equals(user.getStatus())) {
throw new DisabledAccountException();
}

byte[] salt = Encodes.decodeHex(user.getSalt());
return new SimpleAuthenticationInfo(new ShiroUser(
user.getLoginName(), user.getName(), user.getId()),
user.getPassword(), ByteSource.Util.bytes(salt), getName());
} else {
return null;
}
}

/**
* 授权查询回调函数, 进行鉴权但缓存中无用户的授权信息时调用.
*/
@Override
protected AuthorizationInfo doGetAuthorizationInfo(
PrincipalCollection principals) {
ShiroUser shiroUser = (ShiroUser) principals.getPrimaryPrincipal();
// User user = userService.findByLoginName(shiroUser.getLoginName());
List<Role> roles = this.userService
.findRolesByUserId(shiroUser.getId());

SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
for (Role role : roles) {
// 基于Role的权限信息
info.addRole(role.getCode());
}
info.addStringPermissions(this.userService
.findUserPermissions(shiroUser.getId()));
return info;
}

/**
* 更新用户授权信息缓存.
*/
public void clearCachedAuthorizationInfo(String principal) {
SimplePrincipalCollection principals = new SimplePrincipalCollection(
principal, getName());
clearCachedAuthorizationInfo(principals);
}

/**
* 清除所有用户授权信息缓存.
*/
public void clearAllCachedAuthorizationInfo() {
Cache<Object, AuthorizationInfo> cache = getAuthorizationCache();
if (cache != null) {
for (Object key : cache.keys()) {
cache.remove(key);
}
}
}

@PostConstruct
public void initCredentialsMatcher() {
//注释掉原来的匹配器代码
//HashedCredentialsMatcher matcher = new HashedCredentialsMatcher(
// userService.HASH_ALGORITHM);
// matcher.setHashIterations(userService.HASH_INTERATIONS);
// setCredentialsMatcher(matcher);
//设置自定义的安全认证匹配器,注意此处最好将匹配器采用注入的方式设置,若采用new的方式话,在匹配器中将无法使用spring窗口中的其他组件
setCredentialsMatcher(sm4CredentialsMatcher);
}

/**
* 认证密码匹配调用方法
*
* @param authcToken
* @param info
* @throws AuthenticationException
*/
@Override
protected void assertCredentialsMatch(AuthenticationToken authcToken, AuthenticationInfo info)
throws AuthenticationException {
UsernamePasswordToken token = (UsernamePasswordToken) authcToken;
super.assertCredentialsMatch(token, info);
}

public void setUserService(UserService userService) {
this.userService = userService;
}

public void setSm4CredentialsMatcher(SM4CredentialsMatcher sm4CredentialsMatcher) {
this.sm4CredentialsMatcher = sm4CredentialsMatcher;
}

3、修改spring有关shiro的配置

<description>Shiro安全配置</description>

<!-- 单realm配置 -->
<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
<property name="realm" ref="adminRealm" />
<property name="cacheManager" ref="shiroEhcacheManager" />
</bean>

<bean id="adminRealm" class="cn.company.framwork.sys.service.ShiroDbRealm"
depends-on="userRepository,roleRepository">
<property name="userService" ref="userService" />
<!-- 将“安全认证匹配器”注入自定义的Realm中,用于初始化安全认证匹配器 -->
<property name="sm4CredentialsMatcher" ref="sm4CredentialsMatcher" />
</bean>

<!-- 本次改造新增的 安全认证匹配器  -->
<bean id="sm4CredentialsMatcher" class="cn.company.framwork.sys.service.SM4CredentialsMatcher" depends-on="userRepository">
<property name="userService" ref="userService" />
</bean>


4、改造完毕,剩下新建用户时也采用国密SM4算法加密保存数据,可以进行系统登录测试了!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
相关文章推荐