Shiro的基本概念
Apache Shiro是一个强大且易用的Java安全框架,执行身份验证、授权、密码和会话管理。使用Shiro的易于理解的API,您可以快速、轻松地获得任何应用程序,从最小的移动应用程序到最大的网络和企业应用程序。
Shiro的三大核心API
1、subject:用户主体
2、SecurityManager:安全管理器(管理所有的subject,关联Realm)
3、Realm:连接数据的桥梁(连接数据库)
Shiro整合SpringBoot步骤
1、导入shiro与spring整合的依赖:
<!-- 导入shiro与spring整合的依赖: -->
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>1.5.2</version>
</dependency>
2、自定义Relam类(编写一下查询方法与完成一些授权逻辑认证)
package com.gzmu.config;
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
* 需要继承AuthorizingRealm类
* 会实现两个方法
* @author jojo
*
*/
public class MyRealm extends AuthorizingRealm{
/**
* 执行授权
*/
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
// TODO Auto-generated method stub
return null;
}
/**
* 执行认证逻辑
*/
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken arg) throws AuthenticationException {
System.out.println("执行认证"+arg);
//假设获取数据库用户名与密码
String name = "wuhui";;
String password = "123";
//编写Shiro判断逻辑,判断用户名与密码
//判断用户名
UsernamePasswordToken token = (UsernamePasswordToken)arg;
//如果返回的值与数据库中是用户名不匹配
if(!token.getUsername().equals(name)) {
//shiro底层会抛出一个异常
return null;
}
//判断密码
return new SimpleAuthenticationInfo("",password,"");
}
}
3、编写Shiro的配置类(ShiroConfig)
package com.gzmu.config;
import java.util.LinkedHashMap;
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;
@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:必须拥有 “记住我” 功能才能使用
perms:拥有对某个资源的权限才能访问
role: 拥有对某个角色权限才能访问
*/
LinkedHashMap<String, String> filterMap = new LinkedHashMap<String,String>();
// filterMap.put("/add", "authc");
// filterMap.put("/update", "authc");
//放行的用户放在前面
filterMap.put("/test", "anon");
filterMap.put("/login", "anon");
filterMap.put("/*", "authc");
//修改登录页面
shiroFilterFactoryBean.setLoginUrl("/toLogin");
shiroFilterFactoryBean.setFilterChainDefinitionMap(filterMap);
return shiroFilterFactoryBean;
}
/**
* 创建DefaultWebSecurityManager
*/
@Bean(name="securityManager")
public DefaultWebSecurityManager getDefaultWebSecurityManager(@Qualifier("MyRealm") MyRealm myRealm) {
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
//关联Realm
securityManager.setRealm(myRealm);
return securityManager;
}
/**
* 创建Realm对象(第一步)
* @Bean 将方法返回的对象放入Sprin环境进行管理
*/
@Bean(name="MyRealm")
public MyRealm myRealm() {
return new MyRealm();
}
}
4、设置controller测试:
package com.gzmu.controller;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
public class UserController {
/**
* 测试方法
* @return
*/
@RequestMapping("/add")
public String add() {
System.out.println("usercontroller.add");
return "/user/add";
}
@RequestMapping("/update")
public String update() {
System.out.println("usercontroller.update");
return "/user/update";
}
/**
* 设置登录跳转页面
* @return
*/
@RequestMapping("/toLogin")
public String toLogin() {
System.out.println("usercontroller.toLogin");
return "login";
}
/**
* 测试thymeleaf页面是否可用
*/
@GetMapping("/test")
public String testThymeleaf(Model model) {
model.addAttribute("name","huihui");
return "test";
}
/**
* 登录逻辑处理
* @return
*/
@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);
//执行登录方法
try {
//登录成功
subject.login(token);
//跳转到test.html
return "redirect:test";
} catch (UnknownAccountException e) {
// TODO Auto-generated catch block
// e.printStackTrace();
//登录失败: 用户名不存在
model.addAttribute("msg","用户名不存在");
return "login";
}catch (IncorrectCredentialsException e) {
//登录失败: 用户名不存在
model.addAttribute("msg","密码错误");
return "login";
}
}
}
5、添加静态html:
6、运行启动类:
package com.gzmu;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
*
* @author jojo
*
*/
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
7、结果:
登录之后没进行拦截可进行访问