一、shiro前提配置
1)添加依赖
<properties>
<mysql.version>8.0.33</mysql.version>
<druid.version>1.1.10</druid.version>
<java.version>1.8</java.version>
<shiro.version>1.7.1</shiro.version>
<mybatis.version>3.4.2</mybatis.version>
</properties>
<dependencies>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-ehcache</artifactId>
<version>1.8.0</version>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.4.2</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>${druid.version}</version>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring-boot-web-starter</artifactId>
<version>${shiro.version}</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
2)yml相关配置
#数据库相关配置 spring: datasource: driver-class-name: com.mysql.cj.jdbc.Driver type: com.alibaba.druid.pool.DruidDataSource url: jdbc:mysql://localhost:3306/shiro?useSSL=false username: root password: 20001002qql #shiro相关配置 shiro: loginUrl: login.html rememberMeManager: cookie: maxAge: 3600 userNativeSessionManager: true sessionManager: sessionIdUrlRewritingEnabled: false mybatis-plus: type-aliases-package: com.zs.shiro.entity mapper-locations: classpath*:mapper/*Mapper.xml logging: level: com.zs.shiro.dao: debug
二、实现注册
1)创建盐配置类,添加用户时,在serviceImpl中对密码进行盐加密,使用md5进行加密
SaltUtils
package com.zs.shiro.utils;
import java.util.Random;
public class SaltUtils {
public static String getSlat(int n){
char[] chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!@#$%&*".toCharArray();
StringBuilder sb = new StringBuilder();
for (int i = 0; i < n; i++) {
char str = chars[new Random().nextInt(chars.length)];
sb.append(str);
}
return sb.toString();
}
}
Controller
@RequestMapping("/register")
public String register(User user){
Boolean flag = userService.addUser(user);
if (flag){
return "redirect:/login.html";
}
return "redirect:/error.html";
}
ServiceImpl
@Transactional(rollbackFor = Exception.class)
@Override
public Boolean addUser(User user) {
//生成盐
String salt = SaltUtils.getSlat(8);
user.setSalt(salt);
//密码加密
Md5Hash md5Hash = new Md5Hash(user.getPassword(), salt, 1024);
user.setPassword(md5Hash.toHex());
return this.save(user);
}
三、实现登录
1)ShiroConfig配置
@Configuration
public class ShiroConfig {
@Bean
public ShiroFilterChainDefinition shiroFilterChainDefinition(){
DefaultShiroFilterChainDefinition chainDefinition = new DefaultShiroFilterChainDefinition();
Map<String,String> map = new HashMap<>();
//登录放行
map.put("/user/register","anon");
map.put("/user/test","authc");
//免cokkie登录
map.put("/index.html","user");
chainDefinition.addPathDefinitions(map);
return chainDefinition;
}
@Bean
public Realm customRealm(){
CustomRealm customRealm = new CustomRealm();
//设置hashed凭证匹配器
HashedCredentialsMatcher credentialsMatcher = new HashedCredentialsMatcher();
//设置md5加密
credentialsMatcher.setHashAlgorithmName("md5");
//设置散列次数
credentialsMatcher.setHashIterations(1024);
customRealm.setCredentialsMatcher(credentialsMatcher);
return customRealm;
}
}
2)Realm配置
public class CustomRealm extends AuthorizingRealm {
@Autowired
private UserService userService;
//授权
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
/**
* 根据从数据库查询出来的角色对不同用户进行授权,在Controller方法中添加注解
* @RequiresRoles(value={"admin",...}) 用来判断角色
* @RequiresPermissions("order:save:*") 用来判断权限字符串
*/
return null;
}
//角色认证
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
String username = token.getPrincipal().toString();
User user = getUserByUsernameFromMysql(username);
if (user == null){
throw new UnknownAccountException("用户不存在");
}
return new SimpleAuthenticationInfo(user,user.getPassword(), ByteSource.Util.bytes(user.getSalt()),this.getName());
}
private User getUserByUsernameFromMysql(String username) {
return userService.selectUserByUsername(username);
}
}
3)Controller代码实现
@RequestMapping("/login")
public String login(String username,String password,Boolean rememberMe){
Subject subject = SecurityUtils.getSubject();
subject.login(new UsernamePasswordToken(username,password,rememberMe));
return "redirect:/index.html";
}