1、添加Shiro的Maven依赖
<dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-spring</artifactId> <version>1.5.3</version> </dependency>
2、Shiro核心操作说明
Subject 用户 SecurityManager 管理所有用户 Realm 连接数据 //当前用户 Subject subject = SecurityUtils.getSubject(); //封装用户的登录数据 UsernamePasswordToken token = new UsernamePasswordToken(username, password); //执行登录方法,如果没有异常就说明OK了 subject.login(token); //退出登录 subject.logout();
//getPrincipal() 获取到的SimpleAuthenticationInfo中的第一个参数
new SimpleAuthenticationInfo(user,user.getPassword(),"");
User user= (User) subject.getPrincipal();
3、创建UserRealm
public class UserRealm extends AuthorizingRealm { @Autowired UserService userService; //授权 @Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) { System.out.println("执行了授权认证=>doGetAuthorizationInfo"); SimpleAuthorizationInfo info = new SimpleAuthorizationInfo(); //获取当前用户对象 Subject subject = SecurityUtils.getSubject(); User user= (User) subject.getPrincipal(); //设置当前用户权限 info.addStringPermission(user.getRole()); return info; } //认证 @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException { System.out.println("执行了登录认证=>doGetAuthenticationInfo"); //从token中获取用户输入的账号密码 UsernamePasswordToken usertocken=(UsernamePasswordToken)token; //连接真实数据库 User user = userService.selectByName(usertocken.getUsername()); if(user==null){ //如果用户名不一样,返回null 会自动抛出异常 return null; } //密码认证,shiro做 //可以将user放入 Subject subject = SecurityUtils.getSubject(); 中,在授权里面获取 return new SimpleAuthenticationInfo(user,user.getPassword(),""); }
token中的账号密码来源:
//在控制器或者接收用户输入账号密码的地方使用如下代码 UsernamePasswordToken token = new UsernamePasswordToken(username, password);
SecurityUtils.getSubject().login(token);
4、创建Shiro配置类,并设定需要拦截的请求
@Configuration public class ShiroConfig { //shiroFileterFactoryBean @Bean public ShiroFilterFactoryBean shiroFilterFactoryBean(@Qualifier("securityManager")DefaultWebSecurityManager manager){ ShiroFilterFactoryBean bean=new ShiroFilterFactoryBean(); //设置安全管理器 bean.setSecurityManager(manager); //添加shiro的内置过滤器 /* * anno:无需认证就可以访问 * authc:必须认证才能访问 * user:必须拥有 记住我才能用 * perms:拥有对某个资源的权限才能访问 * role:拥有某个角色的权限才能访问 * */ Map<String,String> fileter=new LinkedHashMap<String,String>(); //正常情况下未授权,会跳转到没有授权页面 fileter.put("/user/add","perms[admin]"); fileter.put("/user/update","authc"); bean.setFilterChainDefinitionMap(fileter); //设置登录请求拦截 跳转的路径 bean.setLoginUrl("/tologin"); //未授权拦截 bean.setUnauthorizedUrl("/nopermission"); return bean; } //DefaultWebSecurityManager @Bean public DefaultWebSecurityManager securityManager(@Qualifier("userRealm") UserRealm userRealm){ DefaultWebSecurityManager manager=new DefaultWebSecurityManager(); //关联UserRealm manager.setRealm(userRealm); return manager; } //创建 realm 对象, 需要自定义 //用户认证会放到UserRealm下 //@Bean 默认情况下方法名为对象名 @Bean public UserRealm userRealm(){ return new UserRealm(); } //整合ShiroDialect 用来整合:shiro thymeleaf //getShiroDialect @Bean public ShiroDialect shiroDialect(){ return new ShiroDialect(); }
5、Controller中的登录操作
@RequestMapping("/user/login") public String login(String username,String password,Model model){ //获取当前用户 Subject subject = SecurityUtils.getSubject(); //封装用户的登录数据 UsernamePasswordToken token = new UsernamePasswordToken(username, password); try{ //执行登录方法,如果没有异常就说明OK了 subject.login(token); model.addAttribute("msg","登录成功"); return "/index"; }catch (UnknownAccountException ex){ model.addAttribute("msg","用户名错误"); return "/user/login"; }catch (IncorrectCredentialsException ex){ model.addAttribute("msg","密码错误"); return "/user/login"; }catch (Exception e){ model.addAttribute("msg","未知错误"); return "/user/login"; } }