实现登陆拦截:意思是说,我们访问 某个页面的时候,必须要 给这个页面赋予 一个 过滤器。让它来决定我们 是否能够访问,而当不能访问的时候,则跳转到一个登陆的页面。这就是登陆拦截。
shiro 的内置过滤器有 大概五种:
anon:无需认证就可以访问authc:必须认证 才能访问user:必须 选择 记住我 功能 才可以perms:拥有某个资源的权限才能访问role:拥有某个角色权限才能访问比如我们 现在 做一个 authc,必须通过 认证 才能访问 页面的功能。
@Bean(name = "shiroFilterFactoryBean")
public ShiroFilterFactoryBean getShiroFilterFactoryBean(@Qualifier("defaultWebSecurityManager") DefaultWebSecurityManager defaultWebSecurityManager){
ShiroFilterFactoryBean bean = new ShiroFilterFactoryBean();
bean.setSecurityManager(defaultWebSecurityManager);
// 设置过滤链,可以 拿 一个 链式 Map,所以我们新建一个 链式 Map
Map<String,String> filterMap = new LinkedHashMap<>();
// 这两个页面 都 必须通过 认证才能访问
filterMap.put("/user/add","authc");
filterMap.put("/user/update","authc");
bean.setFilterChainDefinitionMap(filterMap);
// Shiro 没有默认提供给你的 登录页面,得自己去写
// 设置 登录 界面的 url 是什么,这样的话,我们一旦 被过滤器不允许访问 页面,就会 自动的 跳转到 登录页。
bean.setLoginUrl("/toLogin");
return bean;
}
登录页
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Titletitle>
head>
<body>
<h1>登录h1>
<form th:action="@{/login}" method="post">
<p>用户名:<input type="text" name="username">p>
<p>密码:<input type="text" name="password">p>
<p><input type="submit" value="登录">p>
form>
body>
html>
编写 登录 需要的 Controller
@RequestMapping("/login")
public String login(String username, String password, Model model){
// 获取到 subject
Subject subject = SecurityUtils.getSubject();
// 把 username 和 password 封装成 一个 登录 token
UsernamePasswordToken usernamePasswordToken = new UsernamePasswordToken(username, password);
try {
subject.login(usernamePasswordToken);
model.addAttribute("msg","登录成功");
return "index";
}catch (UnknownAccountException e){
model.addAttribute("msg","用户名错误");
return "login";
}catch (IncorrectCredentialsException e){
model.addAttribute("msg","密码错误");
return "login";
}
}
当我们 运行之后,我们就会发现,它 在 login() 的时候,会 去走 User Realm 的认证那个方法。

那也就是说,我们 的 login() 认证 实际上 还需要 我们 自己去写一下。也就是 我们 要在 认证那个 方法里面写一些 东西。

首先我们发现,这个地方 有一个 参数,正好 也是 Token。所以我们 可以 很好的理解为,它是 我们 login() 登录的时候,传递过来的 那个 token 令牌。那么就好办了,我们只需要 做一个 伪数据,进行 判断 即可实现 认证。
// 认证
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
System.out.println("执行了认证");
String name = "root";
String password = "123";
UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken;
if(!token.getUsername().equals(name)){
return null;// 这样的写法 会自动 抛出 异常 UnknowAccountException
}
// 密码认证,shiro 不让我们 开发者去做。它帮我们做。所以不用写
return new SimpleAuthenticationInfo("",password,"");
}


