1、引入依赖
2、自定义一个Realm类
package com.hqy.springbootshiro.shiro;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
/**
* @author hanqingyun
* @date 2020/8/4 14:28
* @project_name springboot-shiro
* @package_name com.hqy.springbootshiro.shiro
* @description 自定义Realm
*/
public class UserRealm extends AuthorizingRealm {
/**
* 执行授权逻辑
*
* @param principalCollection
* @return
*/
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
System.out.println("执行授权逻辑");
return null;
}
/**
* 执行认证的逻辑
*
* @param authenticationToken
* @return
* @throws AuthenticationException
*/
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
System.out.println("执行认证逻辑");
//假设数据库的用户名和密码
String name = "admin";
String password = "123456";
//编写shiro判断逻辑,判断用户名和密码
//1、判断用户名
UsernamePasswordToken token =
(UsernamePasswordToken) authenticationToken;
if (!token.getUsername().equals(name)) {
//用户名不存在
return null;//shiro底层会抛出UnknownAccountException
}
//2、判断密码
return new SimpleAuthenticationInfo("", password, "");
}
}
3、创建Shiro配置类
package com.hqy.springbootshiro.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;
import java.util.LinkedHashMap;
import java.util.Map;
/**
* @author hanqingyun
* @date 2020/8/4 14:24
* @project_name springboot-shiro
* @package_name com.hqy.springbootshiro.shiro
* @description 这是Shiro配置类
*/
@Configuration
public class ShiroConfig {
/**
* 创建ShiroFilterFactoryBean
*/
@Bean
public ShiroFilterFactoryBean getShiroFilterFactory(@Qualifier(
"securityManager") DefaultWebSecurityManager securityManager) {
ShiroFilterFactoryBean shiroFilterFactory = new ShiroFilterFactoryBean();
//设置安全管理器
shiroFilterFactory.setSecurityManager(securityManager);
//添加Shiro内置过滤器
/**
* Shiro内置过滤器,可以实现权限相关的拦截器
* 常用过滤器:
* anon:无需认证(登录)可以访问
* authc:必须认证才可以访问
* user:如果使用了rememberMe功能就可以直接访问
* perms:该资源必须得到资源权限才可以访问
* role:该资源必须得到角色权限才可以访问
*/
//为了保证顺序,采用了LinkedHashMap
Map
filterMap.put("/test", "anon");
filterMap.put("/login", "anon");
/*filterMap.put("/add","authc");
filterMap.put("/edit","authc");*/
filterMap.put("/*", "authc");
//修改跳转的登录页面,不再用shiro默认的login.jsp页面,而是用我们自己定义的login.html页面
shiroFilterFactory.setLoginUrl("/toLogin");
shiroFilterFactory.setFilterChainDefinitionMap(filterMap);
return shiroFilterFactory;
}
/**
* 创建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();
}
}
4、Cotroller类里面写登录逻辑处理
/**
* 登录逻辑处理方法
*
* @param name
* @param password
* @param model
* @return
*/
@RequestMapping("/login")
public String login(String name, String password, Model model) {
System.out.println("进入登录逻辑处理方法");
System.out.println("name===" + name);
/**
* 使用Shiro编写认证操作
*/
//1、获取Subject
Subject subject = SecurityUtils.getSubject();
//2、封装用户数据
UsernamePasswordToken token = new UsernamePasswordToken(name, password);
//3、执行登录方法
try {
subject.login(token);
//只要没有任何异常,就代表登录成功
return "redirect:/test";
} catch (UnknownAccountException e) {
//e.printStackTrace();
//登录失败:用户名不存在
model.addAttribute("msg", "用户名不存在");
return "/login";
} catch (IncorrectCredentialsException e) {
//e.printStackTrace();
//登录失败:密码错误
model.addAttribute("msg", "密码错误");
return "/login";
}
}
5、login.html登录页面
用户登录页面
6、注意事项:
a、用到了thymeleaf模板,所以要引入thymeleaf的依赖
b、控制器类上面一定不能用 @RestController, 要用 @Controller;
控制器类的方法上一定不能用 @ResponseBody;
因为方法的返回值为String类型,若是加了 @ResponseBody,
就会使返回值为json类型的字符串,而不能实现跳转Model视图的作用
@RestController = @ResponseBody + @Controller
7、知识点
a、Shiro内置过滤器,可以实现权限相关的拦截器
常用过滤器:
anon:无需认证(登录)可以访问
authc:必须认证才可以访问
user:如果使用了rememberMe功能就可以直接访问
perms:该资源必须得到资源权限才可以访问
role:该资源必须得到角色权限才可以访问
b、修改跳转的登录页面,不再用shiro默认的login.jsp页面,而是用我们自己定义的login.html页面
shiroFilterFactory.setLoginUrl("/toLogin");