这里写目录标题
第一步 导入依赖
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring-boot-starter</artifactId>
<version>1.7.0</version>
</dependency>
其他的 包自行导入 如 数据库等等
第二步 建立shiroconfig 文件
@Configuration
public class ShiroConfig {
//创建 shirofilter 拦截所有的请求
@Bean
public ShiroFilterFactoryBean getShiroFilterFactoryBean(DefaultWebSecurityManager defaultWebSecurityManager){
ShiroFilterFactoryBean shiroFilterFactoryBean=new ShiroFilterFactoryBean();
//给filter 设置安全管理器
shiroFilterFactoryBean.setSecurityManager(defaultWebSecurityManager);
//配置哪些路径需要 受限
Map<String,String> map =new HashedMap();
map.put("/user/login","anon"); //anon 表示为公共资源
map.put("/index.jsp","authc"); //authc 表示这个资源需要进行认证和授权
map.put("/user/register.jsp","anon");
map.put("/register.jsp","anon");
//设置默认的认证界面路径
shiroFilterFactoryBean.setLoginUrl("/login.jsp");
//将设置好的 map 写入filter
shiroFilterFactoryBean.setFilterChainDefinitionMap(map);
return shiroFilterFactoryBean;
}
//创建安全管理器
@Bean
public DefaultWebSecurityManager getDefaultWebSecurityManager(Realm realm){
DefaultWebSecurityManager defaultWebSecurityManager=new DefaultWebSecurityManager();
//给安全管理器 设置 realm
defaultWebSecurityManager.setRealm(realm);
return defaultWebSecurityManager;
}
//创建自定义的realm
@Bean
public Realm getRealm(){
CusterRealm custerRealm=new CusterRealm();
//修改凭证校验匹配器
HashedCredentialsMatcher matcher = new HashedCredentialsMatcher();
//设置算法
matcher.setHashAlgorithmName("MD5");
//设置散列次数 与你进行加密的数据对应
matcher.setHashIterations(1024);
custerRealm.setCredentialsMatcher(matcher);
//开启缓存管理 可以不管 这是练习的笔记
// custerRealm.setCacheManager(new EhCacheManager());
//custerRealm.setCachingEnabled(true); //开启全局缓存
//custerRealm.setAuthenticationCachingEnabled(true); //开启认证缓存
//custerRealm.setAuthorizationCachingEnabled(true); //开启授权缓存
return custerRealm;
}
}
第三步 创建自定义的realm
public class CusterRealm extends AuthorizingRealm {
@Autowired //这个是 调用数据库的操作
UserService userService;
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
String principal =(String) principalCollection.getPrimaryPrincipal();
System.out.println(principal+" 进入doGetAuthorizationInfo 方法查询权限");
SimpleAuthorizationInfo simpleAuthorizationInfo=new SimpleAuthorizationInfo();
if("zyc".equals(principal)){
simpleAuthorizationInfo.addRole("user");
}
return simpleAuthorizationInfo;
}
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
String principal= (String) authenticationToken.getPrincipal();
System.out.println(userService);
User user=userService.findByname(principal);
if(user!=null) {
//参数一: 数据库中正确的 用户名 参数二数据库中的密码 参数三随机盐的数值 参数四 realm的name
//密码的校验 有默认的方法进行比较 不需要自己进行定义
return new SimpleAuthenticationInfo(user.getUsername(), user.getPassword(), ByteSource.Util.bytes(user.getSalt()), this.getName());
}
return null;
}
}
第四步:关于加密和解密:
加密
public void register(User user) {
//进行MD5 加密 用了盐
String salt = SaltUtils.getsalt(4); //SaltUtils.getsalt自己建立的 随机获取四个符号
//散列次数1024 与 您在config 的进行匹配
Md5Hash md5Hash=new Md5Hash(user.getPassword(),salt,1024);
//把salt 存进数据库 不然登录无法认证
user.setSalt(salt);
user.setPassword(md5Hash.toHex());
userMapper.save(user);
}
//加密获取的随机数代码
public class SaltUtils {
public static String getsalt(int n){
String s="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890~!@#$%^&*()";
char[] chars = s.toCharArray();
StringBuilder sb=new StringBuilder();
for (int i = 0; i < n; i++) {
sb.append(chars[new Random().nextInt(s.length())]);
}
return sb.toString();
}
}
解密:
首先 在 认证的时候 传输盐的值:
然后在config 里面 传输 散列次数和采用的算法匹配器:
补充 :登录与登出:
@GetMapping("/logout")
public String logout(){
Subject subject = SecurityUtils.getSubject();
subject.logout();
return "redirect:/login.jsp";
}
@PostMapping("/login")
public String login(@RequestParam("name") String name,@RequestParam("password") String password){
Subject subject = SecurityUtils.getSubject();
try {
subject.login(new UsernamePasswordToken(name,password));
return "redirect:/index.jsp";
}catch (UnknownAccountException e){
e.printStackTrace();
System.out.println("用户名不存在");
}catch (IncorrectCredentialsException e){
e.printStackTrace();
System.out.println("密码错误");
}
return "redirect:/login.jsp";
}