一. springboot 整合 shiro
1. 引入依赖
<!-- shiro -->
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>1.4.1</version>
</dependency>
2.两个配置文件 ShiroConfig 和 MyShiroRealm
ShiroConfig
@Configuration
public class ShiroConfig {
@Bean
@ConditionalOnMissingBean
public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() {
DefaultAdvisorAutoProxyCreator defaultAAP = new DefaultAdvisorAutoProxyCreator();
defaultAAP.setProxyTargetClass(true);
return defaultAAP;
}
/**
* 密码校验规则HashedCredentialsMatcher
* 这个类是为了对密码进行编码的 ,
* 防止密码在数据库里明码保存 , 当然在登陆认证的时候 ,
* 这个类也负责对form里输入的密码进行编码
* 处理认证匹配处理器:如果自定义需要实现继承HashedCredentialsMatcher
*/
@Bean
public HashedCredentialsMatcher hashedCredentialsMatcher() {
//Shiro自带加密
HashedCredentialsMatcher credentialsMatcher = new HashedCredentialsMatcher();
//散列算法使用md5
credentialsMatcher.setHashAlgorithmName("md5");
//散列次数,1表示md5加密1次
credentialsMatcher.setHashIterations(1);
credentialsMatcher.setStoredCredentialsHexEncoded(true);
return credentialsMatcher;
}
//将自己的验证方式加入容器
@Bean
public MyShiroRealm myShiroRealm() {
MyShiroRealm myShiroRealm = new MyShiroRealm();
myShiroRealm.setCredentialsMatcher(hashedCredentialsMatcher());
return myShiroRealm;
}
//权限管理,配置主要是Realm的管理认证
@Bean
public SecurityManager securityManager() {
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
securityManager.setRealm(myShiroRealm());
return securityManager;
}
@Bean
public ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager) {
ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
shiroFilterFactoryBean.setSecurityManager(securityManager);
Map<String, String> filterMap = new HashMap<String, String>();
// 登出
filterMap.put("/logout", "logout");
// swagger
filterMap.put("/swagger-ui.html", "anon");
filterMap.put("/swagger-resources/**", "anon");
filterMap.put("/v2/**", "anon");
filterMap.put("/webjars/**", "anon");
filterMap.put("/static/**", "anon");
filterMap.put("/reload","anon");
filterMap.put("/csrf","anon");
// 对生成的es查询接口放行
filterMap.put("/ES/**","anon");
// 对所有用户认证
filterMap.put("/**", "authc");
// filterMap.put("/**", "user");
// 登录
shiroFilterFactoryBean.setLoginUrl("/login");
// 错误页面,认证不通过跳转
shiroFilterFactoryBean.setUnauthorizedUrl("/error");
shiroFilterFactoryBean.setFilterChainDefinitionMap(filterMap);
return shiroFilterFactoryBean;
}
/**
* spring与shiro的整合
*/
@Bean
public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager) {
AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);
return authorizationAttributeSourceAdvisor;
}
}
MyShiroRealm
public class MyShiroRealm extends AuthorizingRealm {
@Autowired
private LoginMapper loginMapper;
/**
* 认证登录
* @param token
* @return
* @throws AuthenticationException
*/
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
//token携带了用户信息
UsernamePasswordToken usernamePasswordToken = (UsernamePasswordToken) token;
//获取前端输入的用户名
String userName = usernamePasswordToken.getUsername();
//根据用户名查询数据库中对应的记录
User user = loginMapper.findByName(userName);
//当前realm对象的name
String realmName = getName();
//盐值
ByteSource credentialsSalt = ByteSource.Util.bytes(user.getUsername()+user.getSalt());
//封装用户信息,构建AuthenticationInfo对象并返回
AuthenticationInfo authcInfo = new SimpleAuthenticationInfo(userName, user.getPassword(),
credentialsSalt, realmName);
return authcInfo;
}
// 角色权限,因为我没有使用 shiro 提供的授权方法,所以没有实现这个方法
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
return null;
}
}
二.添加新用户
public void addUser(User user) {
// 生成一个随机4位数
String salt = RandomUtil.randomNumbers(4);
user.setSalt(salt);
// 两个参数,第一个是需要加密的字符串,第二个是盐
Md5Hash hash = new Md5Hash(user.getPassword(), user.getUsername()+salt);
user.setPassword(hash.toString());
mapper.addUser(user);
}