文章目录
SHiro
-
Shrio安全框架更灵活和简单,代码易读使用简单
-
但授权第三方登录需要手动实现
- 配置shrio的核心内容 安全管理器 realm
@Configuration
public class ShiroConfig {
//0.配置shrioFilter
@Bean("shiroFilter")
public ShiroFilterFactoryBean shiroFilter(SecurityManager securityManager) {
ShiroFilterFactoryBean shiroFilter = new ShiroFilterFactoryBean();
shiroFilter.setSecurityManager(securityManager);
//oauth过滤
Map<String, Filter> filters = new HashMap<>();
filters.put("oauth2", new OAuth2Filter());
shiroFilter.setFilters(filters);
Map<String, String> filterMap = new LinkedHashMap<>();
filterMap.put("/index.html", "anon");
filterMap.put("/css/**", "anon");
filterMap.put("/js/**", "anon");
filterMap.put("/doc.html", "anon");
filterMap.put("/v2/api-docs/**", "anon");
filterMap.put("/webjars/**", "anon");
filterMap.put("/druid/**", "anon");
filterMap.put("/app/**", "anon"); //app的拦截用注解方式
filterMap.put("/sys/login", "anon");
filterMap.put("/swagger/**", "anon");
filterMap.put("/v2/api-docs", "anon");
filterMap.put("/swagger-ui.html", "anon");
filterMap.put("/swagger-resources/**", "anon");
filterMap.put("/captcha.jpg", "anon");
filterMap.put("/aaa.txt", "anon");
filterMap.put("/**", "oauth2");
shiroFilter.setFilterChainDefinitionMap(filterMap);
return shiroFilter;
}
//1.配置安全管理器
//用于管理 Shiro 的安全策略,包括认证和授权等功能。
@Bean("securityManager")
public SecurityManager securityManager(OAuth2Realm oAuth2Realm) {
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
securityManager.setRealm(oAuth2Realm);
securityManager.setRememberMeManager(null);
return securityManager;
}
//2.配置realm
@Bean
public Realm OAuth2Realm(){
//MyShiroRealm需要另外实现,在下面将要介绍到
MyShiroRealm myShiroRealm = new MyShiroRealm();
return myShiroRealm;
}
}
-
Shiro 中,你可以使用
@RequiresPermissions
注解来进行权限校验。这个注解标记在方法上时,Shiro 会自动识别并在方法执行前进行权限校验。具体步骤如下:-
开启注解的支持 在上面ShiroConfig加入开启注解
@Configuration public class ShiroConfig { * * * @Bean public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager) { AuthorizationAttributeSourceAdvisor advisor = new AuthorizationAttributeSourceAdvisor(); advisor.setSecurityManager(securityManager); return advisor; } }
-
Controller类的方法上添加
@RequiresPermissions
注解@RequiresPermissions("admin:user:list") @ApiOperation("用户列表") public R list(@RequestParam Map<String, Object> params){ PageUtils page = appUserService.queryPage(params); return R.ok().put("page", page); }
-
方法被调用时候Shrio会自动检查当前用户是否有权限
在判断用户是否具有指定权限时,通常会依赖于其所配置的 Realm(域),一般会实现 doGetAuthorizationInfo 方法来获取用户的权限信息,可以根据具体的业务逻辑从数据库、缓存或其他数据源中查询用户的权限信息
@Component public class MyShiroRealm extends AuthorizingRealm { @Autowired private ShiroService shiroService; @Override public boolean supports(AuthenticationToken token) { return token instanceof OAuth2Token; } /** * 授权(验证权限时调用) */ @Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) { SysUserEntity user = (SysUserEntity)principals.getPrimaryPrincipal(); Long userId = user.getUserId(); //用户权限列表 Set<String> permsSet = shiroService.getUserPermissions(userId); SimpleAuthorizationInfo info = new SimpleAuthorizationInfo(); info.setStringPermissions(permsSet); return info; } /** * 认证(登录时调用) */ @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException { String accessToken = (String) token.getPrincipal(); //根据accessToken,查询用户信息 SysUserTokenEntity tokenEntity = shiroService.queryByToken(accessToken); //token失效 if(tokenEntity == null || tokenEntity.getExpireTime().getTime() < System.currentTimeMillis()){ throw new IncorrectCredentialsException("token失效,请重新登录"); } //查询用户信息 SysUserEntity user = shiroService.queryUser(tokenEntity.getUserId()); //账号锁定 if(user.getStatus() == 0){ throw new LockedAccountException("账号已被锁定,请联系管理员"); } SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(user, accessToken, getName()); return info; } }
-
如上便实现配置SHrio 以及 实现从数据库中查询用户的角色和权限信息,判断是否有权限访问。
其中 doGetAuthenticationInfo是是登陆用到,还未介绍到,下面将介绍登录逻辑
这里登录时手写实现token创建,没用到shrio
@PostMapping("/sys/login")
public Map<String, Object> login(@RequestBody SysLoginForm form)throws IOException {
// 判断验证码 判断用户账号是否存在 是否禁用
todo
//生成token以及过期时间,返回到浏览器并保存到数据库。 这就是sessionID 浏览器请求需携带
R r = sysUserTokenService.createToken(user.getUserId());
return r;
}
Spring Security
Spring Security 是针对Spring项目的安全框架,也是Spring Boot底层安全模块默认的技术选型