①、添加依赖
②、创建ini文件
获取权限相关信息可以通过数据库获取,也可以通过ini配置文件获取
③、认证代码
public class ShiroRun{
public static void main(){
//初始化获取SecurityManager
IniSerucityManagerFactory factory = new IniSecurityManagerFactory("classpath:shiro.ini");
SecurityManager securityManager = factory.getInstance();
SecurityUtils.setSecurityManager(securityManager);
//创建Subject
Subject subject = SecurityUtils.getSubject();
//创建token对象,web应用用户名密码从页面传递
AuthenticationToken = token = new UsernamePasswordToken("zhangsan","z3");
//完成登录
try{
subject.login(token);
System.out.println("登录成功");
//判断角色
boolean hasRole = subject.hasRole("role1");
System.out.println("是否拥有此角色 = " + hasRole);
//判断权限
boolean permitted = subject.isPermitted("user:insert");
System.out.println("是否拥有此权限 = " + permitted);
//也可以通过checkPermission方法,但没有返回值,没权限抛出AuthenticationException
subject.checkPermission("user:select");
}
catch(UnknownAccountException e){
e.printStackTrace();
System.out.println("用户不存在");
}
catch(IncorrectBredentialsException e){
e.printStackTrace();
System.out.println("密码错误")
}
catch(AuthenticationException e){
e.printStackTrace();
}
}
}
授权方式
编程式:
if(subject.hasRole("admin")){
//有权限
}else{
//无权限
}
注解式:
@RequiresRoles("admin")
public void hello(){
//有权限
}
JSP/GSP标签:
<shiro:hasRole name="admin">
<!--有权限-->
</shrio:hasRole>
加密方法
String password = "z3";
Md5Hash md5Hash = new Md5Hash(password);
System.out.println("md5Hash = " + md5Hash);
//带盐加密,明文后面拼接字符串,然后再进行加密
Md5Hash md5Hash2 = new Md5Hash(password,"salt");
System.out.println("md5Hash2 = " + md5Hash2.toHex())
//多次带盐迭代加密(3次迭代加密)
Md5Hash md5Hash3 = new Md5Hash(password,"salt",3);
//使用父类加密
SimpleHash simpleHash = new SimpleHash("MD5",password,"salt",3);
自定义登录认证
public class MyRealm extends AuthenticationRealm{
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken)throws AuthenticationException{
//1.获取身份信息
String principal = authenticationToken.getPrincipal().toString();
//2.获取凭证信息
String password = new String((char[])authenticationToken.getCredentials());
//3.获取数据库中从存储的用户信息
if(principal.equals("zhangsan")){
String pwdInfo = "xxxxx";//数据库中存储的加盐3次迭代的密码
AuthenticationInfo = info = new SimpleAuthenticationInfo(
authenticationToken.getPrincipal(),
pwdInfo,
ByteSource.Util.bytes("salt"),
authenticationToken.getPrincipal().toString()
);
return info;
}
//4.创建
}
}
SpringBoot整合Shiro
①、主要依赖和配置,以及启动类
②、创建数据表以及对应的实体类
③、创建mapper接口
④、创建Service接口及其实现类
⑤、创建Realm
@Component
public class MyRealm extends AuthorizingRealm{
@Autowired
private UserService userService;
//自定义授权方法
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection){
}
//自定义登录认证方法
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken){
//获取用户身份信息
String name = authenticationToken.getPrincipal().toString();
User user = userService.getUserInfoByName(name);
if(user!=null){
AuthenticationInfo info = new SimpleAuthenticationInfo(
authenticationToken.getPrincipal(),
user.getPwd(),
ByteSource.Util.bytes("salt");
authenticationToken.getprincipal().toString()
);
return info;
}
return null;
}
}
⑥、创建配置类
@Configuration
public class ShiroConfig{
@Autowired
private MyRealm myRealm;
@Bean
public DefaultWebSecurityManager defaultWebSecurityManager(){
//创建defaultWebSecurityManager对象
DefaultWebSecurityManager defaultWebSecurityManager = new DefaultWebSecurityManager();
//创建加密对象
HashedCredentialsMatcher matcher = new HashedCredentialsMatcher();
matcher.setHashAlgorithmName("md5");
matcher.setHashIterations(3);//MD5加密迭代3次
//将加密对象存储到myRealm中
myRealm.setCredentialsMatcher(matcher);
//将MyRealm存入defaultWebSecurityManager对象中
defaultWebSecurityManager.setRealm(myRealm);
return defaultWebSecurityManager;
}
/**
设置内置过滤拦截
*/
@Bean
public DefaultShiroFilterChainDefinition shiroFilterChainDefinition(){
DefaultShiroFilterChainDefinition definition = new DefaultShiroFilterChainDefinition();
//设置不认证可以访问的资源
definition.addPathDefinition("/myController/userLogin","anon");
definition.addPathDefinition("/login","anon");
//设置需要进行登录认证的拦截范围
definition.addPathDefinition("/**","authc");
return definition;
}
}
⑦、Controller
@Controller
@RequestMapping("myController")
public class MyController{
//跳转登录页面
@GetMapping("login")
public String login(){
return "login";
}
@GetMapping("uerLogin")
//@ResponseBody 如果不返回数据,需要跳转页面,添加参数session
public String userLogin(String name,String pwd,HttpSession session){
//获取subject
Subject subject = SecurityUtils.getSubject();
//封装请求数据到token
AuthenticationToken token = new UsernamePasswordToken(name,pwd);
try{
subject.login(token);
//return "登录成功";
session.setAttribute("user",token.getPrincipal().toString());
return "main";
}catch(AuthenticationException e){
e.printStackTrace();
System.out.println("登录失败");
return "登录失败";
}
}
}
⑧、Shiro整合thymeleaf
多个realm的认证策略
rememberMe功能
勾选之后,登录之后,关闭浏览器,重新开启浏览器登录,无需再次输入用户名和密码
- defaultWebSecurityManager.setRemberMeManager(rememberManager())
- cookie属性设置
- 创建Shiro的cookie管理对象
- 添加用户过滤器(rememberMe)
- controller中的userLogin方法增加参数rememberMe
- 改造login登录页面
@Configuration
public class ShiroConfig{
@Autowired
private MyRealm myRealm;
@Bean
public DefaultWebSecurityManager defaultWebSecurityManager(){
//创建defaultWebSecurityManager对象
DefaultWebSecurityManager defaultWebSecurityManager = new DefaultWebSecurityManager();
//创建加密对象
HashedCredentialsMatcher matcher = new HashedCredentialsMatcher();
matcher.setHashAlgorithmName("md5");
matcher.setHashIterations(3);//MD5加密迭代3次
//将加密对象存储到myRealm中
myRealm.setCredentialsMatcher(matcher);
//将MyRealm存入defaultWebSecurityManager对象中
defaultWebSecurityManager.setRealm(myRealm);
//设置rememberMe
defaultWebSecurityManager.setRemberMeManager(rememberManager());
return defaultWebSecurityManager;
}
//cookie属性设置
public SimpleCookie rememberMeCookie(){
SimpeCookie cookie = new SimpleCookie("rememberMe");
//设置跨域
cookie.setDomain(domain);
cookie.setPath("/");
cookie.setHttpOnly(true);
cookie.setMaxAge(30*24*60*60);
return cookie;
}
//创建Shiro的cookie管理对象
public CookieRememberMeManager rememberMeManager(){
CookieRememberManager cookieRememberManager = new CookieRememberManager();
cookieRememberMeManager.setCookie(rememberMeCookie());
cookieRememberMeManager.setCipherKey("".getBytes());
return cookieRememberManager;
}
/**
设置内置过滤拦截
*/
@Bean
public DefaultShiroFilterChainDefinition shiroFilterChainDefinition(){
DefaultShiroFilterChainDefinition definition = new DefaultShiroFilterChainDefinition();
//设置不认证可以访问的资源
definition.addPathDefinition("/myController/userLogin","anon");
definition.addPathDefinition("/login","anon");
//设置需要进行登录认证的拦截范围
definition.addPathDefinition("/**","authc");
//添加用户过滤器(rememberMe)
definition.addPathDefinition("/**","user");
return definition;
}
}
//Controller方法
@GetMapping("userLogin")
public String userlogin(String name,String pwd,@RequestParam(defaultValue="false")boolean rememberMe,
HttpSession session){
//AuthenticationToken token = new UsernamePasswordToken(name,pwd,rememberMe);
}
//登录认证验证rememberMe
@GetMapping("userLoginRm")
public String userLogin(HttpSession session){
session.setAttribute("user","rememberMe");
return "main";
}
用户登录认证后登出
通过Shiro过滤器实现
角色认证
授权验证异常处理
实现缓存
public class TestEH{
public static void main(String[] args){
//获取编译目录下的资源流对象
InputStream input = TestEH.class.getClassLoader().getResourceAsStream("eccache.xml");
//获取Ehcache的缓存管理对象
CacheManager cacheManager = new CacheManager(input);
//获取缓存对象
Cache cache = cacheManager.getCache("HelloWorldCache");
//创建缓存数据
Element element = new Element("name","zhang3");
//存入缓存
cache.put(element);
//从缓存中取数据
Element element1 = cache.get("name");
System.out.println("缓存中数据 = " + element1.getObjectValue())
}
}
Shiro整合EhCache