Shiro

发布时间:2026/5/22 16:18:58

Shiro 1什么是shiro官网http://shiro.apache.org/是一款主流的Java安全框架不依赖任何容器可以运行在java SE和Java EE项目中它的主要作用是对访问系统的用户身份认证授权会话管理加密等操作。2shiro核心组件用户角色权限给角色赋予权限给用户赋予角色UsernamePasswordTokenShiro用来封装用户信息使用用户的登录信息来创建Token.SecurityManagerShiro的核心部件负责安全认证和授权SujectShiro 的抽象概念包含了用户信息Realm开发者自定义的模块根据项目需求验证和授权的逻辑全部写在Realm中。AuthenticationInfo用户的角色权限信息集合认证时使用。AuthorzationInfo角色的权限信息集合授权时使用DefaultWebSecurityDManager安全管理开发者自定义的Realm需要注入到DefaultWebSecurityDManager进行管理才能生效。ShiroFilterFactoryBean过滤工厂Shiro的基本运行机制是开发者指定规则Shiro去执行具体的执行操作就是由ShiroFilterFactoryBean创建一个个Filter对象来完成。3运行关系图4运行流程5开发流程6SpringBoot整合Shiro导入依赖dependency groupIdorg.apache.shiro/groupId artifactIdshiro-spring/artifactId version1.4.0/version /dependency这个依赖要和springboot版本适配1.4.0对应2.x的springboot写一个Realmpublic class Accountrealm extends AuthorizingRealm { Autowired private AccountService accountService; /** * 授权 * */ Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) { return null; } /** * 认证 * */ Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException { UsernamePasswordToken token (UsernamePasswordToken) authenticationToken; Account account accountService.findByUsername(token.getUsername()); if (account ! null) { return new SimpleAuthenticationInfo(account, account.getPassword(), getName()); } return null; } }需要为Realm写一个配置类Configuration public class ShiroConfig { Bean public Accountrealm accountrealm(){ return new Accountrealm(); } Bean public DefaultWebSecurityManager securityManager(){ DefaultWebSecurityManager securityManager new DefaultWebSecurityManager(); securityManager.setRealm(accountrealm()); return securityManager; } Bean public ShiroFilterFactoryBean shiroFilterFactoryBean(){ ShiroFilterFactoryBean shiroFilterFactoryBean new ShiroFilterFactoryBean(); shiroFilterFactoryBean.setSecurityManager(securityManager()); return shiroFilterFactoryBean; } }7编写认证和授权规则认证过滤器anon无需认证。authc必须认证。authcBasic需要通过 HTTPBasic 认证。user不一定通过认证只要曾经被 Shiro 记录即可比如记住我。授权过滤器perms必须拥有某个权限才能访问。role必须拥有某个角色才能访问。port请求的端口必须是指定值才可以。rest请求必须基于 RESTfulPOST、PUT、GET、DELETE。ssl必须是安全的 URL 请求协议 HTTPS。8实例创建 3 个页面main.html、manage.html、administator.html访问权限规则如下必须登录才能访问main.html当前用户必须拥有manage权限才能访问manage.html当前用户必须拥有administator角色才能访问administator.html过滤Bean public ShiroFilterFactoryBean shiroFilterFactoryBean(){ ShiroFilterFactoryBean shiroFilterFactoryBean new ShiroFilterFactoryBean(); shiroFilterFactoryBean.setSecurityManager(securityManager()); //权限设置 MapString,String map new HashMap(); map.put(/login,anon); map.put(/main,authc); map.put(/manage,perms[manage]); map.put(/administrator,roles[administrator]); shiroFilterFactoryBean.setFilterChainDefinitionMap(map); //登录设置 shiroFilterFactoryBean.setLoginUrl(/login); return shiroFilterFactoryBean; }遇到的问题前端发送get请求但是login需要post携带参数解决方案PostMapping(/login) public String login(String username, String password) { Subject subject SecurityUtils.getSubject(); UsernamePasswordToken token new UsernamePasswordToken(username, password); try { subject.login(token); } catch (UnknownAccountException e) { return 用户不存在; } catch (IncorrectCredentialsException e) { return 用户名密码错误; } return null; } GetMapping(/login) public String loginPage(RequestParam(required false) String error, Model model) { if (error ! null) { model.addAttribute(error, 用户名或密码错误); } return login; }9最终Realm的权限设置加登录验证/** * 授权 * */ Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) { //获取登录信息 Subject subject SecurityUtils.getSubject(); Account account (Account) subject.getPrincipal(); //设置角色 SetString roles new HashSet(); roles.add(account.getRole()); SimpleAuthorizationInfo info new SimpleAuthorizationInfo(roles); //设置权限 info.addStringPermission(account.getPerms()); return info; } /** * 认证 * */ Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException { UsernamePasswordToken token (UsernamePasswordToken) authenticationToken; Account account accountService.findByUsername(token.getUsername()); if (account ! null) { return new SimpleAuthenticationInfo(account, account.getPassword(), getName()); } return null; }

相关新闻