1.1. 分析Shiro的核心API
Subject: 用户主体(把操作交给SecurityManager)
SecurityManager:安全管理器(关联Realm)
Realm:Shiro连接数据的桥梁
1.2. Spring Boot整合Shiro
1.2.1. 导入shiro与spring整合依赖
修改pom.xml
org.apache.shiroshiro-spring1.4.0
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{ /** * 执行授权逻辑 */@Overrideprotected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection arg0) {System.out.println("执行授权逻辑");return null;} /** * 执行认证逻辑 */@Overrideprotected 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 * */@Configurationpublic class ShiroConfig { /** * 创建ShiroFilterFactoryBean */ @Beanpublic 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();//关联realmsecurityManager.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 * */@Configurationpublic class ShiroConfig { /** * 创建ShiroFilterFactoryBean */@Beanpublic ShiroFilterFactoryBean getShiroFilterFactoryBean(@Qualifier("securityManager")DefaultWebSecurityManager securityManager){ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();//设置安全管理器shiroFilterFactoryBean.setSecurityManager(securityManager);//添加Shiro内置过滤器/** * Shiro内置过滤器,可以实现权限相关的拦截器 * 常用的过滤器: * anon: 无需认证(登录)可以访问 * authc: 必须认证才可以访问 * user: 如果使用rememberMe的功能可以直接访问 * perms: 该资源必须得到资源权限才可以访问 * role: 该资源必须得到角色权限才可以访问 */Map filterMap = new LinkedHashMap();/*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();//关联realmsecurityManager.setRealm(userRealm);return securityManager;}/** * 创建Realm */@Bean(name="userRealm")public UserRealm getRealm(){return new UserRealm();}}
1.4. 实现用户认证(登录)操作
1.4.1. 设计登录页面
html>登录页面
登录
用户名:
密码:
1.4.2. 编写Controller的登录逻辑
/** * 登录逻辑处理 */@RequestMapping("/login")public String login(String name,String password,Model model){/** * 使用Shiro编写认证操作 *///1.获取SubjectSubject subject = SecurityUtils.getSubject();//2.封装用户数据UsernamePasswordToken token = new UsernamePasswordToken(name,password);//3.执行登录方法try {subject.login(token);//登录成功//跳转到test.htmlreturn "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{ /** * 执行授权逻辑 */@Overrideprotected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection arg0) {System.out.println("执行授权逻辑");return null;} /** * 执行认证逻辑 */@Overrideprotected 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相关的依赖
com.alibabadruid1.0.9mysqlmysql-connector-javaorg.mybatis.spring.bootmybatis-spring-boot-starter1.1.1
1.5.2. 配置application.properties
位置:src/main/resources目录下
spring.datasource.driverClassName=com.mysql.jdbc.Driverspring.datasource.url=jdbc:mysql://localhost:3306/testspring.datasource.username=rootspring.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映射文件
<?xml version="1.0" encoding="UTF-8" ?>mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd">SELECT id,NAME,PASSWORDFROMuser where name = #{value}
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; @Servicepublic class UserServiceImpl implements UserService{ //注入Mapper接口@Autowiredprivate UserMapper userMapper;@Overridepublic 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{ /** * 执行授权逻辑 */@Overrideprotected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection arg0) {System.out.println("执行授权逻辑");return null;}@Autowiredprivate UserService userSerivce; /** * 执行认证逻辑 */@Overrideprotected 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(),"");} }
学习视频:可点击“了解更多”