所需依赖:
<!--shiro -->
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-core</artifactId>
<version>1.2.2</version>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>1.2.2</version>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-ehcache</artifactId>
<version>1.2.2</version>
</dependency>
流程:
PS:不止可以配置注解 也可以是 拦截器中通用配置,若是拦截项均会进行鉴权。
基本流程:
登录添加:
// shiro
Subject subject = SecurityUtils.getSubject();
UsernamePasswordToken token=new UsernamePasswordToken(mengpengUser.getUserName(),mengpengUser.getUserPassword());
subject.login(token);
配置 拦截器:
@Configuration
public class ShiroConfig {
// todo
@Bean
public ShiroFilterFactoryBean shiroFilter(SecurityManager securityManager) {
ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
// 配置拦截器的securityManager
shiroFilterFactoryBean.setSecurityManager(securityManager);
Map<String, String> filterChainDefinitionMap = new LinkedHashMap<>();
//<!-- 过滤链定义,从上向下顺序执行,一般将/**放在最为下边 -->:
//<!-- authc:所有url都必须认证通过才可以访问; anon:所有url都都可以匿名访问-->
filterChainDefinitionMap.put("/user/userLogin", "anon");
filterChainDefinitionMap.put("/user/getImge", "anon");
//定义此路径下 指定角色才能访问
filterChainDefinitionMap.put("/jurisdiction/**", "roles[admin]");
filterChainDefinitionMap.put("/**", "authc");
shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
return shiroFilterFactoryBean;
}
@Bean
public Realm myShiroRealm() {
UserRealm userRealm = new UserRealm();
return userRealm;
}
@Bean
public SecurityManager securityManager() {
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
securityManager.setRealm(myShiroRealm());
return securityManager;
}
@Bean(name = "lifecycleBeanPostProcessor")
public static LifecycleBeanPostProcessor lifecycleBeanPostProcessor() {
return new LifecycleBeanPostProcessor();
}
@Bean
@DependsOn({"lifecycleBeanPostProcessor"})
public DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator() {
DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator = new DefaultAdvisorAutoProxyCreator();
advisorAutoProxyCreator.setProxyTargetClass(true);
return advisorAutoProxyCreator;
}
@Bean
public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor() {
AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
authorizationAttributeSourceAdvisor.setSecurityManager(securityManager());
return authorizationAttributeSourceAdvisor;
}
权限获取配置:
(将角色名合 权限名给shiro , shiro 再鉴权的时候可以通过角色名/权限)
package com.haylion.demo.tools;
import com.haylion.demo.dao.UserDao;
import com.haylion.demo.service.UserService;
import org.apache.shiro.SecurityUtils;
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.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import java.util.HashSet;
import java.util.Set;
public class UserRealm extends AuthorizingRealm {
private Logger logger = LoggerFactory.getLogger(this.getClass());
@Autowired
private UserDao userDao;
@Autowired
private UserService userService;
//todo
// 设置此时用户的角色 / 权限
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
logger.info("doGet:" + SecurityUtils.getSubject().getPrincipal());
SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
// 获取当前 "主题" 的id
String id = (String) principalCollection.getPrimaryPrincipal();
// sesion 值会挤掉用户
String name = (String) SecurityUtils.getSubject().getPrincipal();
//此处暂时写死便于测试。实际当问查询缓存/DB 中的数据
Set<String> jurisdiction = new HashSet<>();
Set<String> role = new HashSet<>();
jurisdiction.add("/role/listRole");
role.add("admin");
//分别是插入 具体权限 角色 用于后续鉴权。
authorizationInfo.setStringPermissions(jurisdiction);
authorizationInfo.setRoles(role);
return authorizationInfo;
}
// 登录操作。
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
System.out.println("token.getPrincipal:" + authenticationToken.getPrincipal());
System.out.println("token.getCredentials:" + authenticationToken.getCredentials());
String name = (String) authenticationToken.getPrincipal();
//暂时写死
String password = "yUoX9TlY6zs=";
// 此处可以做 异常处理,
// 用户账户密码校验。
SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(name, password, getName());
return authenticationInfo;
}
}
shiro鉴权源码:
private boolean isPermitted(Permission permission, AuthorizationInfo info) {
Collection<Permission> perms = this.getPermissions(info);
if (perms != null && !perms.isEmpty()) {
Iterator i$ = perms.iterator();
while(i$.hasNext()) {
Permission perm = (Permission)i$.next();
if (perm.implies(permission)) {
return true;
}
}
}
return false;
}
shiro注解权限控制-5个权限注解
@RequiresAuthentication:
使用该注解标注的类,实例,方法在访问或调用时,当前Subject必须在当前session中已经过认证。
@RequiresGuest:
使用该注解标注的类,实例,方法在访问或调用时,当前Subject可以是“gust”身份,不需要经过认证或者在原先的session中存在记录。
@RequiresPermissions:
当前Subject需要拥有某些特定的权限时,才能执行被该注解标注的方法。如果当前Subject不具有这样的权限,则方法不会被执行。
@RequiresRoles:
当前Subject必须拥有所有指定的角色时,才能访问被该注解标注的方法。如果当天Subject不同时拥有所有指定角色,则方法不会执行还会抛出AuthorizationException异常。
@RequiresUser
当前Subject必须是应用的用户,才能访问或调用被该注解标注的类,实例,方法。
感觉比较常用的就是
//鉴权指定权限
@RequiresPermissions({"/role/xxx"})
//指定角色
@RequiresRoles("user")
另就是在 拦截器中全局限制 某个系列的url 指定角色才可访问:
//定义此路径下 指定角色才能访问
filterChainDefinitionMap.put("/jurisdiction/**", "roles[admin]");
感觉比较常用的就是
//鉴权指定权限
@RequiresPermissions({"/role/xxx"})
//指定角色
@RequiresRoles("user")
另就是在 拦截器中全局限制 某个系列的url 指定角色才可访问:
//定义此路径下 指定角色才能访问
filterChainDefinitionMap.put("/jurisdiction/**", "roles[admin]");