Shiro内置过滤器
过滤器
shiro有许多过滤器,可以设置是否需要认证、是否拥有对某资源的权限,是否拥有某个角色等
参数 | 作用 |
---|---|
authc | 需要认证登录才能访问 |
user | 需要认证用户拦截器,表示必须存在用户才能访问 |
anon | 匿名拦截器,不需要登录即可访问的资源,匿名用户或游客,一般用于过滤静态资源。 |
roles | 角色授权拦截器,验证用户是或否拥有角色。参数可写多个,表示某些角色才能通过,多个参数时写 roles[“admin,user”],当有多个参数时必须每个参数都通过才算通过 |
perms | 1、权限授权拦截器,验证用户是否拥有权限 2、参数可写多个,表示需要某些权限才能通过,多个参数时写 perms[“user, admin”],当有多个参数时必须每个参数都通过才算可以 |
authcBasic | httpBasic 身份验证拦截器 |
logout | 退出拦截器,执行后会直接跳转到shiroFilterFactoryBean.setLoginUrl(); 设置的 url |
port | 端口拦截器, 可通过的端口 |
ssl | ssl拦截器,只有请求协议是https才能通过 |
继续之前的代码,给add和update方法增加过滤器。
package com.shirotest.shiro_test.cofig;
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 java.util.LinkedHashMap;
import java.util.Map;
/**
* @Author: 秃头不用洗发水
* @Date: 2021-03-21
* @Description:
*/
@Configuration
public class ShiroConfig {
@Bean(name = "Realm")
public ShiroRealm shiroRealm(){
return new ShiroRealm();
}
@Bean(name = "SecurityManager")
public DefaultWebSecurityManager defaultWebSecurityManager(@Qualifier("Realm") ShiroRealm realm){
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
securityManager.setRealm(realm);
return securityManager;
}
@Bean
public ShiroFilterFactoryBean shiroFilterFactoryBean(@Qualifier("SecurityManager")DefaultWebSecurityManager securityManager){
ShiroFilterFactoryBean bean = new ShiroFilterFactoryBean();
bean.setSecurityManager(securityManager);
//过滤器
Map<String,String> filterMap = new LinkedHashMap<>();
filterMap.put("/user/add","authc");
bean.setFilterChainDefinitionMap(filterMap);
return bean;
}
}
add无法访问
delete可以正常访问
登录页面
写个登录页面,登录后才能访问。
login.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>login</h1>
<form action="">
<p>username:<input type="text" name="username"></p>
<p>password:<input type="password" name="password"></p>
<p><input type="submit"></p>
</form>
</body>
</html>
配置文件添加登录请求
package com.shirotest.shiro_test.cofig;
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 java.util.LinkedHashMap;
import java.util.Map;
/**
* @Author: 秃头不用洗发水
* @Date: 2021-03-21
* @Description:
*/
@Configuration
public class ShiroConfig {
@Bean(name = "Realm")
public ShiroRealm shiroRealm(){
return new ShiroRealm();
}
@Bean(name = "SecurityManager")
public DefaultWebSecurityManager defaultWebSecurityManager(@Qualifier("Realm") ShiroRealm realm){
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
securityManager.setRealm(realm);
return securityManager;
}
@Bean
public ShiroFilterFactoryBean shiroFilterFactoryBean(@Qualifier("SecurityManager")DefaultWebSecurityManager securityManager){
ShiroFilterFactoryBean bean = new ShiroFilterFactoryBean();
bean.setSecurityManager(securityManager);
//过滤器
Map<String,String> filterMap = new LinkedHashMap<>();
filterMap.put("/user/add","authc");
bean.setFilterChainDefinitionMap(filterMap);
//设置登录请求页面
bean.setLoginUrl("/login");
return bean;
}
}
controller层也添加对应方法
package com.shirotest.shiro_test.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
/**
* @Author: 秃头不用洗发水
* @Date: 2021-03-21
* @Description:
*/
@Controller
public class MyController {
@RequestMapping({"/","/index"})
public String toIndex(Model model){
model.addAttribute("msg","shiro_Test:这是index");
return "index";
}
@RequestMapping("/user/add")
public String toadd(){
return "add";
}
@RequestMapping("/user/delete")
public String todelete(){
return "delete";
}
//登录
@RequestMapping("login")
public String tologin(){
return "login";
}
}
测试:
点击add会跳转到登录页面
delete则不会
拦截url也可以使用*,例如 /user/*
用户认证
登录方法
Controller下写个登录方法log
@RequestMapping("/log")
public String log (String username , String password ,Model model){
//获取当前用户subject
Subject subject = SecurityUtils.getSubject();
//封装用户的登录数据(username,password-->token)
UsernamePasswordToken token = new UsernamePasswordToken(username,password);
//登录令牌-->判断权限、角色 , 执行登录方法 ,无异常登录成功 (捕获一下)
try{
subject.login(token); //执行登录方法
return "index";
} catch (UnknownAccountException e) { //用户名错误
model.addAttribute("msg","用户名错误");
return "login";
}catch (IncorrectCredentialsException e){
model.addAttribute("msg","密码错误");
return "login";
}
封装了各种判断
再完善登录页面
<!DOCTYPE html>
<html lang="en" xmlns:th="www.thymeleaf.com">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>login</h1>
<p th:text="${msg}" style="color: red"></p>
<form th:action="@{/log}">
<p>username:<input type="text" name="username"></p>
<p>password:<input type="password" name="password"></p>
<p><input type="submit"></p>
</form>
</body>
</html>
每次点击登录时,就会自动请求验证方法。
用户验证token
可以看到输出验证,接下来在验证方法里完善验证。
先不从数据库取。
package com.shirotest.shiro_test.cofig;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.subject.Subject;
/**
* @Author: 秃头不用洗发水
* @Date: 2021-03-21
* @Description:
*/
public class ShiroRealm extends AuthorizingRealm {
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
System.out.println("授权:doGetAuthorizationInfo");
return null;
}
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
System.out.println("验证:doGetAuthenticationInfo");
String username = "root";
String password = "123456";
//再转化为token
UsernamePasswordToken userToken = (UsernamePasswordToken) authenticationToken;
if (!token.getUsername().equals(username)){
return null;
//抛出异常,unknown
}
//密码验证不需要操作,shiro自动验证
return new SimpleAuthenticationInfo("",password,"");
}
}
要对应
参数分别为 获取当前用户的认证 ,密码 ,认证名 。
自动比对密码,不需要get
演示效果
点击add 需要先登录
输入错误的试试
正确的
完成,后面将用户信息放入数据库中。