一、基本流程概括
- 继承AuthorizingRealm类重写doGetAuthorizationInfo方法实现认证。
- 配置ShiroFilterFactoryBean中的setFilterChainDefinitionMap配置认证规则【PermissionsAuthorizationFilter路径配置权限】
二、code
配置自定义Realm
public class MyShiroRealm extends AuthorizingRealm {
@Autowired
ICompetitionAdminuserService adminuserService;
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
CompetitionAdminuser adminuser = (CompetitionAdminuser) SecurityUtils.getSubject().getSession().getAttribute("adminUser");
Set<String> permissions = adminuserService.findPermissions(adminuser.getId());
SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
permissions.forEach(authorizationInfo::addStringPermission);
return authorizationInfo;
}
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken;
String username = token.getUsername();
QueryWrapper<CompetitionAdminuser> wrapper = new QueryWrapper<>();
wrapper.select("id", "username", "password", "enabled");
wrapper.eq("username", username);
CompetitionAdminuser adminUser = adminuserService.getOne(wrapper, false);
if (adminUser == null) throw new UnknownAccountException("账号错误");
if (adminUser.getEnabled() != 1) throw new LockedAccountException("账号已锁定");
SecurityUtils.getSubject().getSession().setAttribute("adminUser", adminUser);
return new SimpleAuthenticationInfo(
adminUser.getUsername(),
adminUser.getPassword(),
ByteSource.Util.bytes(adminUser.getUsername()),
this.getName()
);
}
}
配置拦截规则【PermissionsAuthorizationFilter】
@Autowired
private ICompetitionPermissionService permissionService;
@Bean
public ShiroFilterFactoryBean shiroFilterFactoryBean() {
ShiroFilterFactoryBean filterFactoryBean = new ShiroFilterFactoryBean();
filterFactoryBean.setSecurityManager(securityManager());
filterFactoryBean.setLoginUrl("/");
filterFactoryBean.setSuccessUrl("/success");
filterFactoryBean.setUnauthorizedUrl("/forbidden");
LinkedHashMap<String, String> map = new LinkedHashMap<>();
map.put("/login", "anon");
List<CompetitionPermission> competitionPermissions = permissionService.selectAll();
for (CompetitionPermission permission : competitionPermissions) {
if (!permission.getUrl().isEmpty()) {
map.put(permission.getUrl(), "perms[" + permission.getUrl() + "]");
}
}
map.put("/**", "authc");
filterFactoryBean.setFilterChainDefinitionMap(map);
return filterFactoryBean;
}
三、shiro组织结构图