目录
实现步骤
1.在pom.xml中导入依赖
2.添加控制层
3.视图层
?4.创建ShiroConfig
5.自定义realm
6.创建pojo类
7.创建mapper接口
8.创建mapper的配置文件
9.创建service和serviceImpl层
?总结:
Subject:任何可以与应用交互的“用户”
SecurityManager:相当于SpringMVC中的DispatcherServlet;是Shiro的心脏;所有具体的交互都通过SecuriTyManager进行控;它管理着所有的Subject,权限认真,授权会话以及缓存管理
Realm:对用户进行认证和授权
实现步骤
- shiro的整合依赖导入
- 编写shiro的核心配置 UserRealm 和ShiroConfig
- 练习登录注册管理权限
1.在pom.xml中导入依赖
<dependenci
<!-- https://mvnrepository.com/artifact/org.apache.shiro/shiro-spring -->
? ? ? ? 导入shiro整合spring的包 ????????<dependency> ? ????????????????? <groupId>org.apache.shiro</groupId> ? ????????????????? <artifactId>shiro-spring</artifactId> ? ????????????????? <version>1.7.1</version> ????????</dependency>
连接数据库,导入数据的jar包
导入shiro-thymeleaf的整合包
<dependencies>
<!--thymeleaf-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!--shiro-->
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>1.8.0</version>
</dependency>
<!--整合mybatis-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.2.0</version>
</dependency>
<!--整合druid数据源-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.2.8</version>
</dependency>
<!--log4j-->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
<!--thymeleaf与shiro整合-->
<dependency>
<groupId>com.github.theborakompanioni</groupId>
<artifactId>thymeleaf-extras-shiro</artifactId>
<version>2.1.0</version>
</dependency>
<!--导入hutool的依赖-->
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>4.5.7</version>
</dependency>
<!--shiro缓存,添加ehcache-->
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-ehcache</artifactId>
<version>1.4.0</version>
</dependency>
</dependencies>
2.添加控制层
@Cotroller
public class MyCotroller{
@RequestMapping({"//","/index"})
public String toIndex(Model model){
model.addAttribute("msg","hello ,shrio")
return "index";
}
@RequestMapping({"/user/update"})
public String toIndex(){
return "user/update";
}
@RequestMapping({"tologin")
public String toIndex(){
return "user/login";
}
@RequestMapping({"login")
public String login(String username ,String password, Model model){
获取当前的用户
Subject subject=SecurityUtils.getSubject()
封装用户的登录数据
UsernamePasswordToken token=new UsernamePasswordToken(username,password);
try{
subject.login(token);//执行登录方法,如果没有异常就说明ok了;
return "index";
}carch(unknowAcoountException e){ //用户名不存在,
model.addAttribute("msg","用户名错误")
return "user/login";
}carch(IncorrectCredentialsExceptione){ //密码不存在,
model.addAttribute("msg","密码错误")
return "user/login";
}
@RequestMapping({"/noauth"})
@RepositoryBody
public String unnoauth(){
return "未经授权无法访问";
}
}
}
3.视图层
index首页
<h1>首页</h1>
<div th:if="session.loginUser==null"> 通过session来判断是否显示页面
<a th:href="@{/tologin}">登录<a>
<div shiro:hasPermission="user:add">
<a th:href="@{/user/add}">添加</a><br>
</div>
<p th:text="${msg}"></p> //在这里显示的model中的数据
<a th:href="@{/user/update}">更新</a><br>
登录界面login
<p th:text="${msy}" style="color:red">
<from th:action="@{/login}" >
<p>用户名:<input type="text" name="username"><p>
<p>密码:<input type="text" name="password"><p>
<p>密码:<input type="subbmit" value="登录"><p>
<from>
user/add界面
<h1>欢迎进入添加页面
user/update 界面
<h1>欢迎进入添加页面
4.Shiro的三大对象
Subject ? 用户 SecurityManager ? 管理所有用户 Realm ? ?连接数据
?4.创建ShiroConfig
Shiro的三大对象
Subject ? 用户
SecurityManager ? 管理所有用户
Realm ? ?连接数据
@Configuration
ShiroFilterFactoryBean
@Bean
public ShiroFilterFactoryBean getShiroFilterFactoryBean(@Qualifier(DafaultWebSecurityManager)DafaultWebSecurityManager dafaultWebSecurityManager){
ShiroFilterFactoryBean bean=new ShiroFilterFactoryBean ();
//设置安全管理器
bean.setSecurityManager(dafaultWebSecurityManager);
return bean;
}
//DafaultWebSecurityManager
@Bean
public DafaultWebSecurityManager getDafaultWebSecurityManager(@Qualifier("userRealm")UserRealm userRealm){
DafaultWebSecurityManager securityManager=new DafaultWebSecurityManager();
关联UserRealm
securityManager.setRealm(userRealm)
return securityManager;
}
//创建realm对象 需要自定义类
@Bean
public UserRealm userRealm(){
return new UserRealm();
}
整合shiroDialect:用来整合 shiro thymeleaf
@Bean
public shiroDialect getshiroDialect(){
return new shiroDialect ();
}
ShiroConfig的补充
@Configuration
ShiroFilterFactoryBean
@Bean
public ShiroFilterFactoryBean getShiroFilterFactoryBean(@Qualifier(DafaultWebSecurityManager)DafaultWebSecurityManager dafaultWebSecurityManager){
ShiroFilterFactoryBean bean=new ShiroFilterFactoryBean ();
//设置安全管理器
bean.setSecurityManager(dafaultWebSecurityManager);
//添加shiro的内置过滤器
/*
anon:无需认证就可以直接访问
aurhc:必须认证了才能访问
user:必须拥有记住我功能才能使用
perms:拥有对某个资源的权限才能使用
role:拥有某个角色权限
*/
Map<String String> fileMap=new linkhashmap<>();
filterMap.put("/user/add","authc");
filterMap.put("/user/update","authc");
或者将这两者合并:
filterMap.put("user/*",authc);
//这个时候,如果我们没有认证。那么就会报错,但是我们目的是如果没有认证我们就想让他跳到登录页面
认证map的集合,这个map的作用就是将没有授权的都进行归类,看是否需要认证是否需要授权等等
授权
filterMap.put("/user/add","perms[user:add]");
如果页面报401的错误就是未授权的意思
//正常情况下会跳转到未授权的页面
bean。setUnatuthore(“/unantohr”)跳入未授权的页面
bean.setFilterChainDefinitionMap(fileMap);
//设置登录的请求
bean.setLoginUrl("/tologin")
return bean;
}
//DafaultWebSecurityManager
@Bean
public DafaultWebSecurityManager getDafaultWebSecurityManager(@Qualifier("userRealm")UserRealm userRealm){
DafaultWebSecurityManager securityManager=new DafaultWebSecurityManager();
关联UserRealm
securityManager.setRealm(userRealm)
return securityManager;
}
//创建realm对象 需要自定义类
@Bean
public UserRealm userRealm(){
return new UserRealm();
}
5.自定义realm
//自定义的UserRealm extend AuthorizingReanlm
public class UserRealm extends AuthorizingReanlm{
//授权
@Override
protected AurhorizationInfo doGetAurhorizationInfo((PrincipalCollection principals{
printin{执行了授权}
return null;
}
//认证
@Override
protected AurhorizationInfo doGetAurhorizationInfo((( AuthenticationToken token{
printin{执行了认证}
return null;
}
}
//自定义的UserRealm的补充
public class UserRealm extends AuthorizingReanlm{
@Autowired
UserMapper userMapper;
//授权
@Override
protected AurhorizationInfo doGetAurhorizationInfo((PrincipalCollection principals{
printin{执行了授权}
为用户授予权限
SimpleAuthorizationInfoinfo simpleAuthorizationInfoinfo=new SimpleAuthorizationInfo();
这是硬编码,每个人都会被授予
info.addStringPermission("user:add");
这是数据库的编码
拿到这个登录的对象
Subject subject=SecurityUtils.getSubject();
User currentUser=(user)subject.getprincipal();
获得授权页面
info.addStringPermission("currentUser.getPerms()");
retrun info;
}
//认证
@Override
protected AurhorizationInfo doGetAurhorizationInfo((( AuthenticationToken token{
printin{执行了认证}
//用户名,密码,数据中获取
伪造数据
String name=“root”
String paswword=“123456”
连接真实数据
UsernamePasswordToken user=(UsernamePasswordToken)token ;
User user=userMapper.querUserByname(userToken.getUsername())
if(user==null){
return null;
}
Subject currentSubject =SubjectUtils.getSubject();
Session session =currentSubject .getsession();
session.setAttRIBUTE("loginUser",User);
//密码进行加密,
也可以将密码加密进行升级,
加密的分类有很多:MD5 MD5盐值加密
return new SimpleAuthenticationInfo(user,user.password,"")//共享user
return null;
}
}
6.创建pojo类
@Date
@AllArgsConstructor
@NoArgsConstructor
public class User{
private int id;
private String name;
private String pwd;
private String perms;//权限的分配
}
7.创建mapper接口
@Reposototy
@Mapper
public interface UserMapper{
public User queryUserByName(String name)
}
8.创建mapper的配置文件
9.创建service和serviceImpl层
public class UserserviceImp implements UserService{
public User queryUserByName(String name);
}
@Service
public class UserserviceImp implements UserService{
@Autowired
UserMapper userMapper;
@Override
public User queryUserByName(String name){
return userMapper.queruser(name);
}
}
?总结:
- Realm和shiroconfig对象是权限管理的关键
- Realm是管理认证和授权,其有一个数据为,user的共享
- shiroconfig,是对一些权限的管理,比如有没有认证,以及有没有授权等等
- 在控制层中,要有对登录用户数据的封装,这样才能使得认证是否正确,和密码认证
- 视图层中,利用thymelef的方法 th:if=“¥{session。名字==null}“是否显示
- 视图层中,利用<div shiro:hasPermission="user:add">是否含有perms的信息,判断有些信息是否显示
- shiro定制化很高,但是内存也很大。
????????
|