1.1. 分析Shiro的核心API Subject: 用户主体(把操作交给SecurityManager)
SecurityManager:安全管理器(关联Realm)
Realm:Shiro连接数据的桥梁
1.2. Spring Boot整合Shiro 1.2.1. 导入shiro与spring整合依赖 修改pom.xml
1.2.2. 自定义Realm类 package com.itheima.shiro;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
/**
-
自定义Realm
-
@author lenovo
*/
public class UserRealm extends AuthorizingRealm{
/**
- 执行授权逻辑
*/
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection arg0) {
System.out.println("执行授权逻辑");
return null;
}
/**
- 执行认证逻辑
*/
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken arg0) throws AuthenticationException {
System.out.println("执行认证逻辑");
return null;
}
}
1.2.3. 编写Shiro配置类(*) package com.itheima.shiro;
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;
/**
-
Shiro的配置类
-
@author lenovo
*/
@Configuration
public class ShiroConfig {
/**
- 创建ShiroFilterFactoryBean
*/
@Bean
public ShiroFilterFactoryBean getShiroFilterFactoryBean(@Qualifier("securityManager")DefaultWebSecurityManager securityManager){
ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
//设置安全管理器
shiroFilterFactoryBean.setSecurityManager(securityManager);
return shiroFilterFactoryBean;
}
/**
- 创建DefaultWebSecurityManager
*/
@Bean(name="securityManager")
public DefaultWebSecurityManager getDefaultWebSecurityManager(@Qualifier("userRealm")UserRealm userRealm){
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
//关联realm
securityManager.setRealm(userRealm);
return securityManager;
}
/**
- 创建Realm
*/
@Bean(name="userRealm")
public UserRealm getRealm(){
return new UserRealm();
}
}
1.3. 使用Shiro内置过滤器实现页面拦截 package com.itheima.shiro;
import java.util.LinkedHashMap;
import java.util.Map;
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;
/**
-
Shiro的配置类
-
@author lenovo
*/
@Configuration
public class ShiroConfig {
/**
- 创建ShiroFilterFactoryBean
*/
@Bean
public ShiroFilterFactoryBean getShiroFilterFactoryBean(@Qualifier("securityManager")DefaultWebSecurityManager securityManager){
ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
//设置安全管理器
shiroFilterFactoryBean.setSecurityManager(securityManager);
//添加Shiro内置过滤器
/**
-
Shiro内置过滤器,可以实现权限相关的拦截器
-
常用的过滤器:
-
anon: 无需认证(登录)可以访问
-
authc: 必须认证才可以访问
-
user: 如果使用rememberMe的功能可以直接访问
-
perms: 该资源必须得到资源权限才可以访问
-
role: 该资源必须得到角色权限才可以访问
*/
Map<String,String> filterMap = new LinkedHashMap<String,String>();
/*filterMap.put("/add", "authc");
filterMap.put("/update", "authc");*/
filterMap.put("/testThymeleaf", "anon");
filterMap.put("/*", "authc");
//修改调整的登录页面
shiroFilterFactoryBean.setLoginUrl("/toLogin");
shiroFilterFactoryBean.setFilterChainDefinitionMap(filterMap);
return shiroFilterFactoryBean;
}
/**
- 创建DefaultWebSecurityManager
*/
@Bean(name="securityManager")
public DefaultWebSecurityManager getDefaultWebSecurityManager(@Qualifier("userRealm")UserRealm userRealm){
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
//关联realm
securityManager.setRealm(userRealm);
return securityManager;
}
/**
- 创建Realm
*/
@Bean(name="userRealm")
public UserRealm getRealm(){
return new UserRealm();
}
}
1.4. 实现用户认证(登录)操作 1.4.1. 设计登录页面
登录
1.4.2. 编写Controller的登录逻辑
/**
- 登录逻辑处理
*/
@RequestMapping("/login")
public String login(String name,String password,Model model){
/**
- 使用Shiro编写认证操作
*/
//1.获取Subject
Subject subject = SecurityUtils.getSubject();
//2.封装用户数据
UsernamePasswordToken token = new UsernamePasswordToken(name,password);
//3.执行登录方法
try {
subject.login(token);
//登录成功
//跳转到test.html
return "redirect:/testThymeleaf";
} catch (UnknownAccountException e) {
//e.printStackTrace();
//登录失败:用户名不存在
model.addAttribute("msg", "用户名不存在");
return "login";
}catch (IncorrectCredentialsException e) {
//e.printStackTrace();
//登录失败:密码错误
model.addAttribute("msg", "密码错误");
return "login";
}
}
1.4.3. 编写Realm的判断逻辑 package com.itheima.shiro;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
/**
-
自定义Realm
-
@author lenovo
*/
public class UserRealm extends AuthorizingRealm{
/**
- 执行授权逻辑
*/
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection arg0) {
System.out.println("执行授权逻辑");
return null;
}
/**
- 执行认证逻辑
*/
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken arg0) throws AuthenticationException {
System.out.println("执行认证逻辑");
//假设数据库的用户名和密码
String name = "eric";
String password = "123456";
//编写shiro判断逻辑,判断用户名和密码
//1.判断用户名
UsernamePasswordToken token = (UsernamePasswordToken)arg0;
if(!token.getUsername().equals(name)){
//用户名不存在
return null;//shiro底层会抛出UnKnowAccountException
}
//2.判断密码
return new SimpleAuthenticationInfo("",password,"");
}
}
1.5. 整合MyBatis实现登录 1.5.1. 导入mybatis相关的依赖
1.5.2. 配置application.properties 位置:src/main/resources目录下
spring.datasource.driverClassName=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/test
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
mybatis.type-aliases-package=com.itheima.domain
1.5.3. 编写User实体 package com.itheima.domain;
public class User {
private Integer id;
private String name;
private String password;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
1.5.4. 编写UserMapper接口 package com.itheima.mapper;
import com.itheima.domain.User;
public interface UserMapper {
public User findByName(String name);
}
1.5.5. 编写UserMapper.xml映射文件
1.5.6. 编写业务接口和实现 接口:
package com.itheima.service;
import com.itheima.domain.User;
public interface UserService {
public User findByName(String name);
}
实现;
package com.itheima.service.impl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.itheima.domain.User;
import com.itheima.mapper.UserMapper;
import com.itheima.service.UserService;
@Service
public class UserServiceImpl implements UserService{
//注入Mapper接口
@Autowired
private UserMapper userMapper;
@Override
public User findByName(String name) {
return userMapper.findByName(name);
}
}
1.5.7. 添加@MapperScan注解 package com.itheima;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
-
SpringBoot启动类
-
@author lenovo
*/
@SpringBootApplication
@MapperScan("com.itheima.mapper")
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
1.5.8. 修改UserRealm package com.itheima.shiro;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.beans.factory.annotation.Autowired;
import com.itheima.domain.User;
import com.itheima.service.UserService;
/**
-
自定义Realm
-
@author lenovo
*/
public class UserRealm extends AuthorizingRealm{
/**
- 执行授权逻辑
*/
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection arg0) {
System.out.println("执行授权逻辑");
return null;
}
@Autowired
private UserService userSerivce;
/**
- 执行认证逻辑
*/
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken arg0) throws AuthenticationException {
System.out.println("执行认证逻辑");
//编写shiro判断逻辑,判断用户名和密码
//1.判断用户名
UsernamePasswordToken token = (UsernamePasswordToken)arg0;
User user = userSerivce.findByName(token.getUsername());
if(user==null){
//用户名不存在
return null;//shiro底层会抛出UnKnowAccountException
}
//2.判断密码
return new SimpleAuthenticationInfo("",user.getPassword(),"");
}
}
注意:本文归作者所有,未经作者允许,不得转载