Shiro介绍:Shiro是一个强大且易用的Java安全框架,执行身份验证、授权、密码和会话管理。使用Shiro的易于理解的API,您可以快速、轻松地获得任何应用程序,从最小的移动应用程序到最大的网络和企业应用程序。
本片文章主要做登录和权限的认证
注:仅作参考,不做任何教学
所有框架:springboot + shiro + thymeleaf
1.pom需要引入
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>1.4.0</version>
</dependency>
<!-- Thymeleaf的依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<!-- Thymeleaf整合shiro标签 -->
<dependency>
<groupId>com.github.theborakompanioni</groupId>
<artifactId>thymeleaf-extras-shiro</artifactId>
<version>2.0.0</version>
</dependency>
2. 自定义Realm
public class Realm extends AuthorizingRealm{
@Autowired
private SysAdminService adminService;/**
* 执行授权逻辑
*/
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
// SysAdmin admin = (SysAdmin)SecurityUtils.getSubject().getPrincipal();//获取登录用户信息
info.addStringPermission("perms[sysAdmin:add]");
//查询该用户的权限
// List<String> list = null;// info.addStringPermissions(list);
return info;
}
/**
* 执行认证逻辑
*/
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
UsernamePasswordToken param = (UsernamePasswordToken)token;
String sysAdminName = param.getUsername();//用户名
SysAdmin admin = adminService.getSysAdminByName(sysAdminName);//查询该用户
if(admin == null) {
return null;
}
//1.判断用户名
if(!sysAdminName.equals(admin.getSysAdminName())) {
//用户名不存在
return null;//shiro底层会自动抛出UnknownAccountException
}
//2.判断密码 第二个参数必须是数据库的密码
return new SimpleAuthenticationInfo(admin,admin.getSysAdminPassword(),"");
}
}
3.shiro配置类
/**
* shiro配置类
* @author Administrator
*
*/
@Configuration
public class ShiroConfig {
/**
* 创建ShiroFilterFactoryBean
*/
@Bean
public ShiroFilterFactoryBean getShiroFilterFactoryBean(@Qualifier("securityManager") DefaultWebSecurityManager securityManager) {
ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
/**
* shiro常用拦截器
* anon: 无需认证就可访问
* authc: 需要认证才能访问
* user :使用rememberMe的功能可直接访问
* perms: 必须有资源的权限才可以访问
* role : 该资源必须得到角色的权限才可以访问
*/
Map<String,String> filterMap = new HashMap<String, String>();
filterMap.put("/sysAdmin/sysAdminlist", "authc");
// filterMap.put("/sysRole/*", "authc");
filterMap.put("/sysLogin", "anon");
filterMap.put("/sysAdmin/sysAdminAdd", "perms[sysAdmin:add]");
filterMap.put("/sysAdmin/sysAdminUpdate", "perms[sysAdmin:update]");
//设置拦截权限
shiroFilterFactoryBean.setFilterChainDefinitionMap(filterMap);
//设置自定义登录页面
shiroFilterFactoryBean.setLoginUrl("/sysLogin");
//设置自定义未授权跳转页面
//shiroFilterFactoryBean.setUnauthorizedUrl("/noAuth/noAuth");
//设置安全管理器
shiroFilterFactoryBean.setSecurityManager(securityManager);
return shiroFilterFactoryBean;
}
/**
* 创建DefaultWebSecurityManager
*/
@Bean(name="securityManager")
public DefaultWebSecurityManager getDefaultWebSecurityManager(@Qualifier("realm") Realm realm) {
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
//关联realm
securityManager.setRealm(realm);
return securityManager;
}
/**
* 创建Realm
*/
@Bean(name="realm")
public Realm getRealm() {
return new Realm();
}
@Bean
public ShiroDialect getShiroDialect(){
return new ShiroDialect();
}
/**
* 开启shiro aop注解支持. 使用代理方式;所以需要开启代码支持;
*
* @param securityManager
* @return
*/
@Bean
public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager manager) {
AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
authorizationAttributeSourceAdvisor.setSecurityManager(manager);
return authorizationAttributeSourceAdvisor;
}
@Bean(name = "simpleMappingExceptionResolver")
public SimpleMappingExceptionResolver createSimpleMappingExceptionResolver() {
SimpleMappingExceptionResolver resolver = new SimpleMappingExceptionResolver();
Properties mappings = new Properties();
mappings.setProperty("DatabaseException", "databaseError");// 数据库异常处理
mappings.setProperty("UnauthorizedException", "/user/403");
resolver.setExceptionMappings(mappings); // None by default
resolver.setDefaultErrorView("error"); // No default
resolver.setExceptionAttribute("exception"); // Default is "exception"
System.out.println("===================="+resolver);
return resolver;
}
}
4. 登录
/**
* 登录校验
* @param admin
* @return
* @throws Exception
*/
@RequestMapping(value="/checkLogin" ,method=RequestMethod.POST)
@ResponseBody
public JSONObject checkLogin(SysAdmin admin) throws Exception {
JSONObject json = new JSONObject();
/**
* shiro 认证操作
*/
//1.获取Subject对象
Subject subject = SecurityUtils.getSubject();
//2.封装用户数量
UsernamePasswordToken token = new UsernamePasswordToken(admin.getSysAdminName(), admin.getSysAdminPassword());
//3.执行登录方法
try {
subject.login(token);
}catch (UnknownAccountException e) {
json.put("msg", "noExist");
json.put("info", "用户名不存在");
return json;
}catch(IncorrectCredentialsException e) {
json.put("msg", "errorPwd");
json.put("info", "密码不正确");
return json;
}
json.put("msg", "success");
json.put("info", "登录成功");
json.put("url", "/Bmsc/menu/sysMenuList");
return json;
}
5.页面 切记此处的权限 sysAdmin:add必须要与之前shiro配置类中添加的权限要一致
<div class="operation mb15" shiro:hasPermission="sysAdmin:add">
<button class="btn button_btn bg-deep-blue" type="button" onclick="add()">添加管理</button>
</div>