访问系统的用户,主体可以是用户,程序等。进行认证的都成为主体。
是主体(subject)进行身份认证的标识,标识必须具有唯一性,如用户名、手机号、邮箱地址等,一个主体可以
有多个身份,但是必须有一个主身份(Primary Principal),比如手机号登录,或者账户登录。
是只有主体自己知道的安全信息,如密码、证书等。
授权可简单理解为who对what(which)进行How操作:
主体需要访问系统中的资源。
如系统菜单、页面、按钮、类方法、系统商品信息等。资源包括资源类型和资源实例,比如商品信息为资源类型,类型为t01的商品为资源实例,编号为001的商品信息也属于资源实例。
规定了主体对资源的操作许可,权限离开资源没有意义,如用户查询权限、用户添加权限、某个类方法的调用权限、编号为001用户的修改权限等,通过权限可知主体对哪些资源都有哪些操作
许可。
权限分为粗颗粒和细颗粒,粗颗粒权限是指对资源类型的权限,细颗粒权限是对资源实例的权限
subject.isAuthenticated() //登录是否成功
subject.hasRole("admin") //验证是否有admin角色
subject.hasAllRoles(Arrays.asList("admin","super")) //验证是否包含所有角色
subject.hasRoles(Arrays.asList("admin","super")) //验证是否有某一个角色
subject.isAuthenticated() //验证是否登录成功
subject.isPermitted("user:delete") //验证用户是否有该权限
<shiro:authenticated></shiro:authenticated> //已经认证
<shiro:notAuthenticated></shiro:notAuthenticated> //未认证
<shiro:principal></shiro:principal> //获取主身份信息
<shiro:hasRole name="admin"></shiro:hasRole> //判断是否有该角色
<shiro:hasAnyRoles name="admin,super"></shiro:hasAnyRoles> //判断是否有某一个角色(有一个就可执行)
<shiro:hasPermission name="banner:delete"></shiro:hasPermission> //判断是否有该权限
引入依赖
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring-boot-web-starter</artifactId>
<version>1.4.1</version>
</dependency>
package cn.czboy.shiro;
import org.apache.shiro.cache.MemoryConstrainedCacheManager;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.HashMap;
@Configuration
public class ShiroFilter {
@Bean
public ShiroFilterFactoryBean shiroFilterFactoryBean(DefaultWebSecurityManager securityManager) {
System.out.println("===========shiroFilter");
ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
HashMap<String,String> map = new HashMap<>();
map.put("/subject/**","anon");
map.put("/login.jsp","anon");
map.put("/index.jsp","anon");
map.put("/**","authc");
shiroFilterFactoryBean.setFilterChainDefinitionMap(map);
shiroFilterFactoryBean.setLoginUrl("/login.jsp");//设置拦截后跳转的网页
shiroFilterFactoryBean.setSecurityManager(securityManager);
return shiroFilterFactoryBean;
}
@Bean
public DefaultWebSecurityManager securityManager(MyRealm myRealm) {
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
MemoryConstrainedCacheManager cache = new MemoryConstrainedCacheManager();
securityManager.setCacheManager(cache);
securityManager.setRealm(myRealm);
return securityManager;
}
@Bean
public MyRealm myRealm() {
MyRealm myRealm = new MyRealm();
return myRealm;
}
}
创建自定义Realm
package cn.czboy.shiro;
import cn.czboy.entity.Role;
import cn.czboy.entity.Subject;
import cn.czboy.mapper.SubjectDao;
import cn.czboy.utils.SpringContextUtil;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.beans.factory.annotation.Autowired;
import java.util.List;
public class MyRealm extends AuthorizingRealm {
/**授权*/
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
String username = (String)principalCollection.getPrimaryPrincipal();
SubjectDao subjectDao = (SubjectDao)SpringContextUtil.getBean(SubjectDao.class);
//根据主体获取角色
List<Role> roles = subjectDao.findByRole(username);
HashSet<String> set = new HashSet<>();
ArrayList<String> arrayList = new ArrayList<>();
SimpleAuthorizationInfo authorizationInfo = null;
if(primaryPrincipal.equals(admin.getUsername())){
authorizationInfo = new SimpleAuthorizationInfo();
for(RoleDto role:roles){
arrayList.add(role.getRoleName());
String id = role.getId();
//根据角色查权限
List<String> permissionss = adminService.findByPermission(id);
for(String key:permissionss){
set.add(key);
}
}
authorizationInfo.addStringPermissions(set);//权限赋值
authorizationInfo.addRoles(arrayList);//角色赋值
}
return authorizationInfo;
}
/**认证*/
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
String username = (String)authenticationToken.getPrincipal();
String password = new String((char[]) authenticationToken.getCredentials());
SubjectDao subjectDao = (SubjectDao)SpringContextUtil.getBean(SubjectDao.class);
Subject subject = subjectDao.findByUserName(username);
AuthenticationInfo authenticationInfo = null;
if (subject == null) {
throw new UnknownAccountException("账户不存在!");
}
if (!subject.getUsername().equals(username)) {
throw new UnknownAccountException("用户名错误!");
}
if (!subject.getPassword().equals(password)) {
throw new IncorrectCredentialsException("密码错误!");
}
authenticationInfo = new SimpleAuthenticationInfo(subject.getUsername(), subject.getPassword(), this.getName());
System.out.println("================="+subject);
return authenticationInfo;
}
}
SubjectController
package cn.czboy.controller;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.annotation.RequiresRoles;
import org.apache.shiro.subject.Subject;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/subject")
public class SubjectController {
/**用户登陆*/
@RequestMapping("/login")
public String login(String username,String password) {
System.out.println("========="+username);
System.out.println("========="+password);
Subject subject = SecurityUtils.getSubject();
UsernamePasswordToken token = new UsernamePasswordToken(username, password);
try {
subject.login(token);
return "yes";
} catch (UnknownAccountException e) {
System.out.println(e.getMessage());
return "no";
} catch (IncorrectCredentialsException e) {
System.out.println(e.getMessage());
return "no";
}
}
}