文章目录
- SHiro
- Spring Security
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@Beanpublic Realm OAuth2Realm(){//MyShiroRealm需要另外实现,在下面将要介绍到MyShiroRealm myShiroRealm = new MyShiroRealm();return myShiroRealm;}}
-
Shiro 中,你可以使用
@RequiresPermissions
注解来进行权限校验。这个注解标记在方法上时,Shiro 会自动识别并在方法执行前进行权限校验。具体步骤如下:-
开启注解的支持 在上面ShiroConfig加入开启注解
@Configuration public class ShiroConfig {***@Beanpublic 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 {@Autowiredprivate ShiroService shiroService;@Overridepublic boolean supports(AuthenticationToken token) {return token instanceof OAuth2Token;}/*** 授权(验证权限时调用)*/@Overrideprotected 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;}/*** 认证(登录时调用)*/@Overrideprotected 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底层安全模块默认的技术选型
Spring Security