image-20211215211130028

环境搭建

引入shiro依赖

1
2
3
4
5
6
<!--引入shiro整合springboot依赖-->
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring-boot-starter</artifactId>
<version>1.5.3</version>
</dependency>

1.创建配置类

image-20211216150841438

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/**
* 用来整合shiro相关的配置类
*/
@Configuration
public class ShiroConfig {


//1.创建shiroFilter 负责拦截所有请求
@Bean
public ShiroFilterFactoryBean getShiroFilterFactoryBean(DefaultWebSecurityManager defaultWebSecurityManager) {}

//2.创建安全管理器 web环境下
@Bean
public DefaultWebSecurityManager getDefaultWebSecurityManager(Realm realm) {}

//3.创建自定义realm
@Bean
public Realm getRealm() {}
}

2.配置shiroFilterFactoryBean

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
@Bean
public ShiroFilterFactoryBean getShiroFilterFactoryBean(DefaultWebSecurityManager defaultWebSecurityManager) {
ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();

//给filter设置安全管理器
shiroFilterFactoryBean.setSecurityManager(defaultWebSecurityManager);

//配置系统受限资源
//配置系统公告资源
HashMap<String, String> map = new HashMap<>();
//map.put("/index.jsp","authc");//authc 请求这个资源需要认证和授权
map.put("/user/login", "anon");
map.put("/user/register", "anon");
map.put("/user/getImage", "anon");
map.put("/register.jsp", "anon");
map.put("/**", "authc");//authc 请求这个资源需要认证和授权

shiroFilterFactoryBean.setFilterChainDefinitionMap(map);

//默认认证界面路径
//shiroFilterFactoryBean.setLoginUrl("/login.jsp");

return shiroFilterFactoryBean;
}

shiroFilterFactoryBean.setFilterChainDefinitionMap(map);

配置系统公共、受限资源

  • anon 公共
  • authc 受限

一般map.put("/**", "authc")将所有资源拦截,然后主要配置放行不需要受限的资源。

常见过滤器

注意: shiro提供和多个默认的过滤器,我们可以用这些过滤器来配置控制指定url的权限:

配置缩写 对应的过滤器 功能
anon AnonymousFilter 指定url可以匿名访问
authc FormAuthenticationFilter 指定url需要form表单登录,默认会从请求中获取usernamepassword,rememberMe等参数并尝试登录,如果登录不了就会跳转到loginUrl配置的路径。我们也可以用这个过滤器做默认的登录逻辑,但是一般都是我们自己在控制器写登录逻辑的,自己写的话出错返回的信息都可以定制嘛。
authcBasic BasicHttpAuthenticationFilter 指定url需要basic登录
logout LogoutFilter 登出过滤器,配置指定url就可以实现退出功能,非常方便
noSessionCreation NoSessionCreationFilter 禁止创建会话
perms PermissionsAuthorizationFilter 需要指定权限才能访问
port PortFilter 需要指定端口才能访问
rest HttpMethodPermissionFilter 将http请求方法转化成相应的动词来构造一个权限字符串,这个感觉意义不大,有兴趣自己看源码的注释
roles RolesAuthorizationFilter 需要指定角色才能访问
ssl SslFilter 需要https请求才能访问
user UserFilter 需要已登录或“记住我”的用户才能访问

3.配置WebSecurityManager

1
2
3
4
5
6
@Bean
public DefaultWebSecurityManager getSecurityManager(Realm realm){
DefaultWebSecurityManager defaultWebSecurityManager = new DefaultWebSecurityManager();
defaultWebSecurityManager.setRealm(realm);
return defaultWebSecurityManager;
}

4.创建自定义realm

1
2
3
4
5
//创建自定义realm
@Bean
public Realm getRealm(){
return new CustomerRealm();
}

认证实现

1.编写login.jsp

image-20211216152502108

1
2
3
4
5
<form action="${pageContext.request.contextPath}/user/login" method="post">
用户名:<input type="text" name="username" > <br/>
密码 : <input type="text" name="password"> <br>
<input type="submit" value="登录">
</form>

2.开发controller

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
@Controller
@RequestMapping("user")
public class UserController {
/**
* 用来处理身份认证
* @param username
* @param password
* @return
*/
@RequestMapping("login")
public String login(String username,String password){
//获取主体对象
Subject subject = SecurityUtils.getSubject();
try {
subject.login(new UsernamePasswordToken(username,password));
return "redirect:/index.jsp";
} catch (UnknownAccountException e) {
e.printStackTrace();
System.out.println("用户名错误!");
}catch (IncorrectCredentialsException e){
e.printStackTrace();
System.out.println("密码错误!");
}
return "redirect:/login.jsp";
}
}

3.开发realm

1
2
3
4
5
6
7
8
9
10
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
System.out.println("==========================");
String principal = (String) token.getPrincipal();
if("kylin".equals(principal)){
return new SimpleAuthenticationInfo(principal,"123",this.getName());
}
return null;
}
}

当前只有以下用户信息

  • 用户名:kylin
  • 密码:123

image-20211216153510922

启动项目,登录成功!

认证功能没有md5和随机盐的认证就实现了

退出认证

1
2
3
4
5
6
7
8
9
10
11
12
13
14
@Controller
@RequestMapping("user")
public class UserController {
/**
* 退出登录
*
*/
@RequestMapping("logout")
public String logout(){
Subject subject = SecurityUtils.getSubject();
subject.logout();//退出用户
return "redirect:/login.jsp";
}
}

subject.logout();退出用户

MD5、Salt的认证实现