shiro的配置主要集中在 ShiroFilterFactoryBean 中
关于权限:
anon:无需认证就可以访问
authc:必须认证了才能访问
user:必须用有了 记住我 功能才能用
perms:拥有对某个资源的权限才能访问
role:拥有某个角色权限才能访问
1、登录拦截
ShiroConfig 中 ShiroFilterFactoryBean
给控制器添加2个 "必须认证了才能访问"
也就是使用 authc
@Bean(name = "shiroFilterFactoryBean") public ShiroFilterFactoryBean shiroFilterFactoryBean(@Qualifier("defaultWebSecurityManager")DefaultWebSecurityManager defaultWebSecurityManager){ ShiroFilterFactoryBean bean=new ShiroFilterFactoryBean(); bean.setSecurityManager(defaultWebSecurityManager); /* * anon:无需认证就可以访问 * authc:必须认证了才能访问 * user:必须用有了 记住我 功能才能用 * perms:拥有对某个资源的权限才能访问 * role:拥有某个角色权限才能访问 */ Map<String ,String> filterMap = new LinkedHashMap<>(); filterMap.put("/user/add","authc"); filterMap.put("/user/update","authc"); bean.setFilterChainDefinitionMap(filterMap); return bean; }
访问测试
点击 add 和 update
都出现这个404页面
2、添加登录页面
登录页面
login.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <h1>登录</h1> <hr> <form action=""> <p>用户名:<input type="text" name="username"></p> <p>密码:<input type="text" name="password"></p> <p><input type="submit"></p> </form> </body> </html>
对应controller
@RequestMapping("/toLogin") public String toLogin(){ return "login"; }
shiro配置类
1.add 与 update 跳转合并
filterMap.put("/user/*","authc");
2.添加一个登录跳转
bean.setLoginUrl("/toLogin");
@Bean(name = "shiroFilterFactoryBean") public ShiroFilterFactoryBean shiroFilterFactoryBean(@Qualifier("defaultWebSecurityManager")DefaultWebSecurityManager defaultWebSecurityManager){ ShiroFilterFactoryBean bean=new ShiroFilterFactoryBean(); bean.setSecurityManager(defaultWebSecurityManager); /* * anon:无需认证就可以访问 * authc:必须认证了才能访问 * user:必须用有了 记住我 功能才能用 * perms:拥有对某个资源的权限才能访问 * role:拥有某个角色权限才能访问 */ Map<String ,String> filterMap = new LinkedHashMap<>(); filterMap.put("/user/*","authc"); bean.setFilterChainDefinitionMap(filterMap); bean.setLoginUrl("/toLogin"); return bean; }
测试
点击 add 和 update
出现登录页面
3、认证
controller中
1.获取当前的用户
Subject subject = SecurityUtils.getSubject();
2.封装用户的登录数据
UsernamePasswordToken token = new UsernamePasswordToken(username, password);
3.执行登录方法,如果没有异常说明OK
subject.login(token);
4.对应异常
UnknownAccountException:用户名不存在
IncorrectCredentialsException:密码错误
@RequestMapping("/login") public String login(String username, String password, Model model) { //获取当前的用户 Subject subject = SecurityUtils.getSubject(); //封装用户的登录数据 UsernamePasswordToken token = new UsernamePasswordToken(username, password); try { subject.login(token); //执行登录方法,如果没有异常说明OK return "index"; } catch (UnknownAccountException e) { //用户名不存在 model.addAttribute("msg", "用户名错误"); return "login"; } catch (IncorrectCredentialsException e) { //密码错误 model.addAttribute("msg", "密码错误"); return "login"; } }
认证具体任务
UserRealm 中 doGetAuthenticationInfo
先将数据写死测试
只需判断用户名,密码shiro判断
//认证 @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException { System.out.println("执行了=>认证doGetAuthenticationInfo"); //用户名+密码 String name = "root"; String password="123"; UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken; if (!token.getUsername().equals(name)){ return null; //return null 会自动抛出异常 } //密码认证,shiro做 return new SimpleAuthenticationInfo("",password,""); }
login.html
<!DOCTYPE html> <html lang="en" xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <h1>登录</h1> <hr> <form th:action="@{/login}"> <p>用户名:<input type="text" name="username"></p> <p>密码:<input type="text" name="password"></p> <p><input type="submit"></p> </form> <p th:text="${msg}" style="color: red"></p> </body> </html>
测试
用户名错误
密码错误
都正确
访问add
访问update