shrio中hashedCredentialsMatcher密碼匹配示例詳解
類圖如下:

SimpleCredentialsMatcher是明文匹配,也是shrio框架默認(rèn)的比對方式,網(wǎng)上的例子多是此方式。實(shí)際項目中,數(shù)據(jù)庫中的密碼一般是密文,此時密碼的匹配需使用HashedCredentialsMatcher完成。
處理過程
在controller中通過Subject的login(token)將接收過來用戶賬號和密碼(明文)交給shrio框架,示例代碼如下

其次通過HashedCredentialsMatcher告訴shrio使用加密方式;

最后通過AuthorizingRealm,將數(shù)據(jù)庫中獲取的密碼,告訴shrio框架,shrio處理完成后返回處理結(jié)果。

示例代碼
數(shù)據(jù)庫創(chuàng)建表user,結(jié)構(gòu)如下:
CREATE TABLE `user` ( `id` bigint(20) NOT NULL AUTO_INCREMENT, `name` varchar(50) DEFAULT NULL, `psw` varchar(200) DEFAULT NULL, `user_right` varchar(300) DEFAULT NULL, `create_time` date DEFAULT NULL, `salt` varchar(100) DEFAULT NULL, PRIMARY KEY (`id`) )
在dao完成根據(jù)登錄名獲取實(shí)體對象和增加用戶兩個方法,略過。service代碼如下,保存代碼時,密碼使用sha256加密,鹽隨機(jī)獲取20位隨機(jī)數(shù)
@Service("UserService")
public class UserServiceImpl extends ServiceImpl<UserDao, UserEntity> implements UserService {
@Override
public UserEntity getUserByname(String loginName) {
return baseMapper.queryByUserName(loginName);
}
@Override
public boolean save(UserEntity user) {
user.setCreateTime(new Date());
String salt = RandomStringUtils.randomAlphanumeric(20);
user.setPsw(new Sha256Hash(user.getPsw(), salt).toHex());//sha256加密
user.setSalt(salt);
try {
baseMapper.insert(user);
return true;
} catch (Exception e) {
return false;
}
}
}
controller代碼如下
@RestController
public class UserController {
@Autowired
private UserService userService;
@PostMapping("/login")
public Map<String, Object> login(@RequestParam Map<String, Object> params) {
String username=params.get("username").toString();
String password=params.get("password").toString();
String result = "已登錄";
Subject currentUser = SecurityUtils.getSubject();
UsernamePasswordToken token = new UsernamePasswordToken(username, password);
if (!currentUser.isAuthenticated()) {
try {
currentUser.login(token);// 會觸發(fā)com.shiro.config.MyShiroRealm的doGetAuthenticationInfo方法
result = "登錄成功";
} catch (UnknownAccountException e) {
result = "用戶名錯誤";
} catch (IncorrectCredentialsException e) {
e.printStackTrace();
result = "密碼錯誤";
}
}
return R.ok(result);
}
@GetMapping("/logout")
public void logout() {
Subject currentUser = SecurityUtils.getSubject();
UserEntity user = (UserEntity)currentUser.getPrincipal();
System.out.println(user.getName());
currentUser.logout();
}
@RequestMapping("/user/add")
public String add(@RequestBody UserEntity user) {
userService.save(user);
System.out.println("新增用戶");
return "hello";
}
}
使用ShiroConfig 代替xml配置文件方式
@Configuration
public class ShiroConfig {
@Bean
public ShiroFilterFactoryBean shiroFilter(SecurityManager securityManager) {
ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
//設(shè)置自定義的securityManager
shiroFilterFactoryBean.setSecurityManager(securityManager);
//設(shè)置默認(rèn)登錄的url,身份認(rèn)證失敗會訪問該URL
shiroFilterFactoryBean.setLoginUrl("/login");
//設(shè)置成功,會訪問該url
shiroFilterFactoryBean.setSuccessUrl("/success");
//設(shè)置未授權(quán)界面,權(quán)限認(rèn)證失敗會訪問該url
shiroFilterFactoryBean.setUnauthorizedUrl("/notRole");
//進(jìn)行攔截器配置
Map<String, String> filterChainDefinitionMap = new LinkedHashMap<>();
// <!-- authc:所有url都必須認(rèn)證通過才可以訪問; anon:所有url都都可以匿名訪問-->
filterChainDefinitionMap.put("/webjars/**", "anon");
filterChainDefinitionMap.put("/login", "anon");
filterChainDefinitionMap.put("/", "anon");
filterChainDefinitionMap.put("/front/**", "anon");
filterChainDefinitionMap.put("/user/add", "perms[add]");
filterChainDefinitionMap.put("/admin/**", "authc");
filterChainDefinitionMap.put("/user/**", "authc");
//主要這行代碼必須放在所有權(quán)限設(shè)置的最后,不然會導(dǎo)致所有 url 都被攔截 剩余的都需要認(rèn)證
filterChainDefinitionMap.put("/**", "authc");
//配置logout過濾器
filterChainDefinitionMap.put("/logout","logout"); shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
return shiroFilterFactoryBean;
}
@Bean
public SecurityManager securityManager() {
DefaultWebSecurityManager defaultSecurityManager = new DefaultWebSecurityManager();
defaultSecurityManager.setRealm(customRealm());
return defaultSecurityManager;
}
@Bean
public CustomRealm customRealm() {
CustomRealm customRealm = new CustomRealm();
//SimpleCredentialsMatcher明文匹配,hashedCredentialsMatcher加鹽匹配
customRealm.setCredentialsMatcher(hashedCredentialsMatcher());
return customRealm;
}
@Bean
public HashedCredentialsMatcher hashedCredentialsMatcher() {
HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher();
hashedCredentialsMatcher.setHashAlgorithmName("SHA-256");
hashedCredentialsMatcher.setHashIterations(1);
return hashedCredentialsMatcher;
}
}
Realm中代碼如下:
public class CustomRealm extends AuthorizingRealm {
@Autowired
private UserService userService;
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
//授權(quán)部分代碼略
return null;
}
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
String loginName = (String) authenticationToken.getPrincipal();
UserEntity user= userService.getUserByname(loginName);
if (user == null) { // 沒找到帳號
throw new UnknownAccountException();
}
// 交給AuthenticatingRealm使用CredentialsMatcher進(jìn)行密碼匹配
SimpleAuthenticationInfo authenticationInfo =
new SimpleAuthenticationInfo(user, user.getPsw(), ByteSource.Util.bytes(user.getSalt()),getName());
return authenticationInfo;
}
測試,使用張三登錄


以上就是shrio中hashedCredentialsMatcher密碼匹配示例詳解的詳細(xì)內(nèi)容,更多關(guān)于shrio中hashedCredentialsMatcher密碼匹配的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Java List接口與Iterator接口及foreach循環(huán)使用解析
這篇文章主要介紹了Java List接口與Iterator接口及foreach循環(huán),主要包括List接口與Iterator接口及foreach循環(huán)具體的使用方法和代碼,需要的朋友可以參考下2022-04-04
SpringBoot中使用JdbcTemplate訪問Oracle數(shù)據(jù)庫的案例詳解
JdbcTemplate是Spring框架中的一個核心類,用于簡化Java應(yīng)用程序與關(guān)系型數(shù)據(jù)庫的交互操作,本文給大家介紹SpringBoot中使用JdbcTemplate訪問Oracle數(shù)據(jù)庫的方法,感興趣的朋友跟隨小編一起看看吧2023-10-10
mybatis的映射xml中動態(tài)設(shè)置orderby方式
這篇文章主要介紹了mybatis的映射xml中動態(tài)設(shè)置orderby方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-11-11
spring cloud gateway 全局過濾器的實(shí)現(xiàn)
全局過濾器作用于所有的路由,不需要單獨(dú)配置,我們可以用它來實(shí)現(xiàn)很多統(tǒng)一化處理的業(yè)務(wù)需求,這篇文章主要介紹了spring cloud gateway 全局過濾器的實(shí)現(xiàn),小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2019-03-03

