Apache Shiro 是一个功能强大且易于使用的 Java 安全(权限)框架。Shiro 可以完成:认证、授权、加密、会话管理、与 Web 集成、缓存 等。借助 Shiro 您可以快速轻松地保护任何应用程序——从最小的移动应用程序到最大的 Web 和企业应用程序。
官方网址: https://shiro.apache.org/
引入依赖
org.apache.shiro shiro-spring-boot-web-starter 1.9.0
指定登录路径
shiro:loginUrl: /user/login
创建数据库
user表
role表
user_role表
permissions表
role_permissions表
省略Mybatis查询数据库代码
@Component("authorizer")
public class MyRealm extends AuthorizingRealm {@Autowiredprivate UserService userService;/*** 自定义授权方法* @param principalCollection* @return*/@Overrideprotected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {//1 创建对象,存储当前登录的用户的权限和角色SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();//2 获取当前用户身份信息String name = principalCollection.getPrimaryPrincipal().toString();List roles = userService.getUserRoles(name);//3 存储角色info.addRoles(roles);//4 获取用户角色的权限信息List permissions=new ArrayList<>();for (String role : roles) {List ps = userService.getUserPermission(role);permissions.addAll(permissions);}//5 存储权限信息info.addStringPermissions(permissions);//6 返回return info;}/*** 自定义登录方法* @param authenticationToken* @return* @throws AuthenticationException*/@Overrideprotected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {//获取用户身份信息String name = authenticationToken.getPrincipal().toString();//查询用户信息User user = userService.getUserByName(name);if (user!=null){AuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(name,//用户名user.getPwd(),//密码ByteSource.Util.bytes("salt"),//加盐字符getName()//realm名称);return authenticationInfo;}return null;}}
@Configuration
public class ShiroConfig {//配置自定义Realm@Beanpublic MyRealm myRealm(){return new MyRealm();}//配置 SecurityManager@Beanpublic DefaultWebSecurityManager defaultWebSecurityManager(){//1 创建 defaultWebSecurityManager 对象DefaultWebSecurityManager manager = new DefaultWebSecurityManager();//2 创建加密对象,并设置相关属性HashedCredentialsMatcher matcher = new HashedCredentialsMatcher();//2.1 采用 md5 加密matcher.setHashAlgorithmName("md5");//2.2 迭代加密次数matcher.setHashIterations(3);//3 将加密对象存储到 myRealm 中myRealm().setCredentialsMatcher(matcher);//4 将 myRealm 存入 defaultWebSecurityManager 对象manager.setRealm(myRealm());//5 返回 defaultWebSecurityManager 对象return manager;}//配置 Shiro 内置过滤器拦截范围@Beanpublic DefaultShiroFilterChainDefinition shiroFilterChainDefinition(){DefaultShiroFilterChainDefinition definition = new DefaultShiroFilterChainDefinition();//设置不认证可以访问的资源definition.addPathDefinition("/user/login","anon");//配置退出过滤器definition.addPathDefinition("/logout","logout");//设置需要进行登录认证的拦截范围definition.addPathDefinition("/**","authc");return definition;}
}
@RestController
@RequestMapping("/user")
@ResponseBody
public class UserController {@PostMapping(path = "/login",produces = "application/json")public String login(@RequestBody User user){try {//1 获取 Subject 对象Subject subject = SecurityUtils.getSubject();//2 封装请求数据到 token 对象中UsernamePasswordToken token = new UsernamePasswordToken(user.getName(),user.getPwd());subject.login(token);return "登录成功!";}catch (LockedAccountException e){return "账号封禁";}catch (UnknownAccountException e) {e.printStackTrace();return "用户不存在";}catch (IncorrectCredentialsException e) {e.printStackTrace();return "密码错误";}catch (AuthenticationException e) {e.printStackTrace();return "登录失败!";}}//登录认证验证角色@RequiresRoles("admin")@GetMapping("/roles")public String userLoginRoles() {return "验证角色成功";}//登录认证验证权限@RequiresPermissions("user:delete")@GetMapping("/permissions")public String userLoginPermissions() {return "验证权限成功";}
}
@ControllerAdvice
@ResponseBody
public class PermissionsException {@ExceptionHandler(UnauthorizedException.class)public String unauthorizedException(Exception ex){return "无权限";}}
AuthenticationStrategy class | 描述 |
---|---|
AtLeastOneSuccessfulStrategy | 只要有一个(或更多)的 Realm 验证成功,那么认证将视为成功 |
FirstSuccessfulStrategy | 第一个 Realm 验证成功,整体认证将视为成功,且后续 Realm 将被忽略 |
AllSuccessfulStrategy | 所有 Realm 成功,认证才视为成功 |
ModularRealmAuthenticator 内置的认证策略默认实现是 AtLeastOneSuccessfulStrategy 方式。
//配置 SecurityManager
@Bean
public DefaultWebSecurityManager defaultWebSecurityManager(){//1 创建 defaultWebSecurityManager 对象DefaultWebSecurityManager defaultWebSecurityManager = new DefaultWebSecurityManager();//2 创建认证对象,并设置认证策略ModularRealmAuthenticator modularRealmAuthenticator = new ModularRealmAuthenticator();modularRealmAuthenticator.setAuthenticationStrategy(new AllSuccessfulStrategy());defaultWebSecurityManager.setAuthenticator(modularRealmAuthenticator);//3 封装 myRealm 集合List list = new ArrayList<>();list.add(myRealm1);list.add(myRealm2);//4 将 myRealm 存入 defaultWebSecurityManager 对象defaultWebSecurityManager.setRealms(list);//5 返回return defaultWebSecurityManager;
SessionManager由SecurityManager管理。Shiro提供了三种实现:
Session session = SecurityUtils.getSubject().getSession();
session.setAttribute(“key”,”value”)
学习内容来自尚硅谷
上一篇:网上流行语大咖什么意思