要配置和使用Shiro,需要进行以下步骤:
- 添加Shiro的依赖:在pom.xml文件中添加Shiro的依赖项。
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring-boot-starter</artifactId>
<version>1.7.0</version>
</dependency>
- 创建一个Shiro配置类:创建一个类并加上
@Configuration
注解,用于配置Shiro的相关配置。
@Configuration
public class ShiroConfig {
@Bean
public ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager) {
ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
shiroFilterFactoryBean.setSecurityManager(securityManager);
// 配置拦截器链
Map<String, String> filterChainDefinitionMap = new LinkedHashMap<>();
filterChainDefinitionMap.put("/login", "anon"); // 允许匿名访问的路径
filterChainDefinitionMap.put("/logout", "logout"); // 配置登出路径
filterChainDefinitionMap.put("/**", "authc"); // 其他路径都需要认证
shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
return shiroFilterFactoryBean;
}
@Bean
public SecurityManager securityManager(UserRealm userRealm) {
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
securityManager.setRealm(userRealm);
return securityManager;
}
@Bean
public UserRealm userRealm() {
return new UserRealm();
}
}
- 创建一个Realm类:创建一个类并继承
AuthorizingRealm
类,实现认证和授权的相关逻辑。
public class UserRealm extends AuthorizingRealm {
@Autowired
private UserService userService;
// 认证
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
// 获取用户名和密码
String username = (String) token.getPrincipal();
String password = new String((char[]) token.getCredentials());
// 根据用户名从数据库查询用户信息
User user = userService.getUserByUsername(username);
// 用户不存在
if (user == null) {
throw new UnknownAccountException();
}
// 验证密码
if (!password.equals(user.getPassword())) {
throw new IncorrectCredentialsException();
}
// 身份验证通过,返回身份信息
SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(user, password, getName());
return authenticationInfo;
}
// 授权
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
// 获取当前登录用户
User user = (User) principals.getPrimaryPrincipal();
// 查询用户的角色和权限信息,添加到授权信息中
Set<String> roles = userService.getRolesByUsername(user.getUsername());
authorizationInfo.setRoles(roles);
Set<String> permissions = userService.getPermissionsByUsername(user.getUsername());
authorizationInfo.setStringPermissions(permissions);
return authorizationInfo;
}
// 清除缓存,当用户的权限发生变动时调用
public void clearCache() {
PrincipalCollection principals = SecurityUtils.getSubject().getPrincipals();
super.clearCache(principals);
}
}
- 创建一个自定义登录接口:创建一个Controller类,使用Shiro提供的
Subject
类进行登录认证。
@RestController
public class LoginController {
@PostMapping("/login")
public String login(String username, String password) {
Subject subject = SecurityUtils.getSubject();
// 创建用户名/密码身份验证Token
UsernamePasswordToken token = new UsernamePasswordToken(username, password);
try {
// 进行登陆认证
subject.login(token);
// 登陆成功,返回成功信息
return "login success";
} catch (AuthenticationException e) {
// 登陆失败,返回错误信息
return "login failed";
}
}
@GetMapping("/logout")
public String logout() {
Subject subject = SecurityUtils.getSubject();
subject.logout();
return "logout success";
}
}
- 配置启用Shiro:在
application.properties
文件中添加配置。
# 开启Shiro的注解支持
shiro.enableAnnotation=true
完成以上步骤后,就可以通过访问/login
接口进行登录认证,通过访问/logout
接口进行注销。其他路径需要认证后才能访问。授权逻辑可以根据实际需求进行修改。