本文共 5972 字,大约阅读时间需要 19 分钟。
org.apache.shiro shiro-spring 1.3.2 com.github.theborakompanioni thymeleaf-extras-shiro 2.0.0
spring: datasource: username: root password: admin url: jdbc:mysql://localhost:3306/abc?serverTimezone=UTC&useUnicode=true&characterEncoding=utf8&useSSL=false driver-class-name: com.mysql.cj.jdbc.Driver# type: com.albaba.druid.pool.DruidDataSourcemybatis: //mybatis配置文件路径 config-location: classpath:mybatis/mybatis-config.xml //mapper文件路径 mapper-locations: classpath:mybatis/mapper/*.xml
package com.example.config;import java.util.HashMap;import java.util.Map;import org.apache.shiro.spring.web.ShiroFilterFactoryBean;import org.apache.shiro.web.mgt.DefaultWebSecurityManager;import org.springframework.beans.factory.annotation.Qualifier;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import at.pollux.thymeleaf.shiro.dialect.ShiroDialect;@Configurationpublic class ShiroConfig { //拦截器, 拦截到相关映射地址后跳转到登录页面 @Bean public ShiroFilterFactoryBean getShiroFilterFactoryBean(@Qualifier("securityManager")DefaultWebSecurityManager securityManager){ ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean(); //设置安全管理器 shiroFilterFactoryBean.setSecurityManager(securityManager); /** * Shiro内置过滤器, 实现相关权限相关的拦截器 * 常用的过滤器: * anon: 无需认证(登录)可以访问 * authc: 必须认证才可以访问 * user: 如果使用rememberMe的功能可以直接访问 * perms: 该资源必须得到资源权限才可以访问 * role: 该资源必须得到角色权限才可以访问 */ //一定要用 LinkedHashMap 否则出错 MapfilterMap = new LinkedHashMap<>(); //授权拦截器, 拦截后会调用 doGetAuthorizationInfo 方法进行授权逻辑 filterMap.put("/test/add", "perms[user:abc]"); filterMap.put("/test/update", "perms[user:add]"); //拦截类似 /test/add 的路径,跳转到登录页面 filterMap.put("/test/**", "authc"); //设置自定义登录认证页面 shiroFilterFactoryBean.setLoginUrl("/toLogin"); //设置自定义未授权页面 shiroFilterFactoryBean.setUnauthorizedUrl("/unauthorizedUrl"); shiroFilterFactoryBean.setFilterChainDefinitionMap(filterMap); return shiroFilterFactoryBean; } @Bean("securityManager") public DefaultWebSecurityManager getDefaultWebSecurityManager(@Qualifier("userRealm")UserRealm userRealm){ DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager(); securityManager.setRealm(userRealm); return securityManager; } @Bean("userRealm") public UserRealm getRealm(){ return new UserRealm(); } /** * 配置ShiroDialect, 用于thymeleaf和shiro标签配合使用 */ @Bean public ShiroDialect getShiroDialect(){ return new ShiroDialect(); }}
package com.example.config;import org.apache.shiro.SecurityUtils;import org.apache.shiro.authc.AuthenticationException;import org.apache.shiro.authc.AuthenticationInfo;import org.apache.shiro.authc.AuthenticationToken;import org.apache.shiro.authc.SimpleAuthenticationInfo;import org.apache.shiro.authc.UsernamePasswordToken;import org.apache.shiro.authz.AuthorizationInfo;import org.apache.shiro.authz.SimpleAuthorizationInfo;import org.apache.shiro.realm.AuthorizingRealm;import org.apache.shiro.subject.PrincipalCollection;import org.apache.shiro.subject.Subject;import org.springframework.beans.factory.annotation.Autowired;import com.example.bean.User;import com.example.service.UserService;public class UserRealm extends AuthorizingRealm{ @Autowired UserService userService; //授权 @Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection arg0) { System.out.println("执行授权逻辑"); SimpleAuthorizationInfo info = new SimpleAuthorizationInfo(); //获取当前登录用户 Subject subject = SecurityUtils.getSubject(); //是从doGetAuthenticationInfo方法返回的user得到的 System.out.println("subject.getPrincipal();" + subject.getPrincipal()); User user = (User) subject.getPrincipal(); User dbUser = userService.findById(user.getId()); //添加资源的授权字符串 System.out.println(user.getPerms()); info.addStringPermission(user.getPerms()); return info; } //认证 @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken arg0) throws AuthenticationException { System.out.println("执行认证逻辑"); //subject.login(token) 传来的token UsernamePasswordToken token = (UsernamePasswordToken) arg0; //判断用户名是否存在 User user = userService.findByuserName(token.getUsername()); if(user==null){ //用户名不存在 //返回 null, shiro 底层会抛出UnKnowAccountException异常 return null; } /* * 2、判断密码是否正确 * 1)、错误的话 shiro 底层会抛出IncorrectCredentialsException异常 * 2)、正确的话返回true */ return new SimpleAuthenticationInfo(user/*方法的携带信息*/, user.getPassword(), ""/*shiro的名称*/); }}
@RequestMapping("/login") public String login(String name, String password, Model model){ /** * 使用Shiro对页面的账号与密码进行认证 */ //1、获取Subject Subject subject = SecurityUtils.getSubject(); //2、封装用户数据, 形成一个令牌 UsernamePasswordToken token = new UsernamePasswordToken(name, password); //3、执行登录方法 try{ //执行此方法时会调用到 doGetAuthenticationInfo 认证方法 subject.login(token); //登录成功 //成功后 shiro 会保存session, session在就不会再拦截了 return "success"; } catch(UnknownAccountException e){ //登录失败 model.addAttribute("msg", "用户不存在"); return "forward:/toLogin"; } catch(IncorrectCredentialsException e){ //登录失败 model.addAttribute("msg", "密码错误"); return "forward:/toLogin"; } }
Insert title here 登陆页面
Insert title here name
进入用户添加功能: 用户添加进入用户更新功能: 用户更新登录: login
//获取当前 subject 对象 Subject subject = SecurityUtils.getSubject(); //判断是否有验证过 if(subject.isAuthenticated()) //有验证即登录了就退出 subject.logout();
转载地址:http://tyern.baihongyu.com/