shiro

shiro很适合用来解决登录认证与权限控制

shiro就是过滤器做请求拦截,拦截url,redis里面存session,代表是支持分布式的,

session是用户信息,

依赖如下:

        <!-- shiro插件 -->
        <dependency>
            <groupId>org.apache.shiro</groupId>
            <artifactId>shiro-spring</artifactId>
            <version>1.4.2</version>
        </dependency>
        <!-- shiro+redis缓存插件 -->
        <dependency>
            <groupId>org.crazycake</groupId>
            <artifactId>shiro-redis</artifactId>
            <version>2.4.2.1-RELEASE</version>
        </dependency>

搭建步骤:

现在主流是和SpringBoot项目整合

@Configuration
public class ShiroConfig {
    
    @Value("${shiro.session.timeout}")
    private Long globalSessionTimeout;
    
    @Value("${spring.redis.host}")
    private String redisHost;
    
    @Value("${spring.redis.port}")
    private Integer redisPort;
    
    @Autowired
    private OnsAppService appService;
    
    
    //@Bean
    public TokenFilter tokenFilter(){
        TokenFilter f=new TokenFilter();
        return f;
    };
    
    public FeignSimpleFilter feignSimpleFilter() {
        return new FeignSimpleFilter();
    }
    
    //@Bean
    public SignatureFilter signatureFilter(){
        return new SignatureFilter();
    };
    //@Bean
    private ApiFilter apiFilter(){
        ApiFilter a=new ApiFilter();
        a.setAppService(appService);
        return a;
    }
    
    
    @Bean
    public ShiroDBRealm shiroDBRealm(){
        return new ShiroDBRealm();//此处自己实现了shiro的认证方法,后续有介绍
    };
    
    @Bean
    public DefaultWebSecurityManager securityManager(){
        DefaultWebSecurityManager d=new DefaultWebSecurityManager();
        d.setSessionManager(sessionManager());
        d.setRealm(shiroDBRealm());
        d.setCacheManager(cacheManager());
        return d;
    }
    
    public CacheManager cacheManager(){
        RedisCacheManager redisCacheManager = new RedisCacheManager();
        redisCacheManager.setRedisManager(redisManager());
        return redisCacheManager;
    }
    
    @Bean
    public DefaultWebSessionManager sessionManager(){
        DefaultWebSessionManager dwsm=new DefaultWebSessionManager();
        dwsm.setGlobalSessionTimeout(globalSessionTimeout);
        //dwsm.setGlobalSessionTimeout(6000);
        dwsm.setSessionDAO(redisSessionDAO());
        dwsm.getSessionIdCookie().setName("JSID");
        return dwsm;
    }
    
    @Bean
    public RedisSessionDAO redisSessionDAO(){
        RedisSessionDAO rs=new RedisSessionDAO();
        rs.setRedisManager(redisManager());
        return rs;
    }
    
    
    @Bean
    public RedisManager redisManager(){
        RedisManager rm=new RedisManager();
        rm.setHost(redisHost);
        //rm.setExpire(globalSessionTimeout.intValue()/1000);
        rm.setExpire(60);
        rm.setPort(redisPort);
        return rm;
    }
    
    @Bean
    public ShiroFilterFactoryBean shiroFilter(){
        ShiroFilterFactoryBean sff=new ShiroFilterFactoryBean();
        sff.setSecurityManager(securityManager());
        sff.setLoginUrl("/login");
        sff.setSuccessUrl("/home");
        sff.setUnauthorizedUrl("/login");
        Map<String,Filter> filters=new HashMap<>();
        //filters.put("tkf", tokenFilter());
        filters.put("snf", signatureFilter());
        filters.put("af", apiFilter());
        filters.put("feignFilter", feignSimpleFilter());
        

        ItsmSpiFilter a = new ItsmSpiFilter();
//        a.setAppService(appService);
        filters.put("spi", a);
        RestTokenFilter restTokenFilter = new RestTokenFilter();
        filters.put("rest", restTokenFilter);
        
        sff.setFilters(filters);
        Map<String,String> filterChain = new LinkedHashMap<>();
        
        filterChain.put("/favicon.ico", "anon");
        filterChain.put("/login", "anon");
        filterChain.put("/updatePwd", "anon");
        filterChain.put("/toLogin", "anon");
        filterChain.put("/captcha.png", "anon");
        filterChain.put("/logout", "logout");
        filterChain.put("/static/**", "anon");
        filterChain.put("/forgetPwd/**", "anon");
        filterChain.put("/cxf/**", "anon");
        filterChain.put("/ras-itsm/authentication", "anon");
        
        filterChain.put("/ras-itsm/**", "anon,af");
        filterChain.put("/pocOrderApi/**", "anon");
        filterChain.put("/itsm-spi/**", "anon,spi");
        
        //filterChain.put("/ras-itsm/**", "anon");
        
        filterChain.put("/itsm-spi/v1/**", "anon,snf");
        filterChain.put("/weixin/**", "anon");
        filterChain.put("/rmsPern/valiDate*", "anon");
        filterChain.put("/rmsPern/registerUser.do", "anon");
        filterChain.put("/rmsPern/emailConfirmUser", "anon");
        filterChain.put("/rmsPern/itsm/savePerson", "anon");
        filterChain.put("/api/oauth2/**", "anon");
        filterChain.put("/api/**", "anon,af");
        filterChain.put("/syncData/**", "anon,af");
        filterChain.put("/restApi/getToken", "anon");
        //filterChain.put("/restApi/**", "anon");
        filterChain.put("/restApi/**", "anon");

        filterChain.put("/org/queryOrgBranchListByCost", "anon,feignFilter");
        filterChain.put("/feign/**", "anon,feignFilter");


        filterChain.put("/**", "authc");
        sff.setFilterChainDefinitionMap(filterChain);
        
        return sff;
    }
    @Bean
    public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager) {
        AuthorizationAttributeSourceAdvisor advisor = new AuthorizationAttributeSourceAdvisor();
        advisor.setSecurityManager(securityManager);
        return advisor;
    }
    @Bean
    public static LifecycleBeanPostProcessor lifecycleBeanPostProcessor(){
        return new LifecycleBeanPostProcessor();
    }

shiro的redisMangeer对session和权限数据的缓存时长都有影响,当我们刷新页面session的缓存有效时长会刷新为最长时效,但是权限数据缓存不会随之刷新,权限数据缓存到期后,session时间若没有失效则会自动重新加载权限数据到缓存中,若session失效则需要重新登录,登录完成后session与权限的过期时间全部更新为最新时效

配置类中的Realm

查询出用户信息与用户角色权限信息

public class ShiroDBRealm extends AuthorizingRealm {

    private Logger log = LoggerFactory.getLogger(ShiroDBRealm.class);
    
    
    @Autowired
    private UserService userService;
    @Autowired
    private SysResourceService sysResourceService;
    @Autowired
    private StringRedisTemplate stringTpl;
    @Autowired
    private OAuthService oauthService;

    //功能权限中更改的部分在这能查出来,系统权限和项目权限都加到了info中
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        Set<String> roles = new HashSet<String>();
        Set<String> permissions = new HashSet<String>();
        SysUser user = (SysUser) principals.getPrimaryPrincipal();
        log.info("用户 :account:[{}],userId:[{}] 进行权限认证 !", user.getAccount(), user.getId());
        List<SysRole> sysRoles = userService.getUserRoles(user.getId());
        for (SysRole r : sysRoles) {
            roles.add(r.getRoleCode());
            List<SysResource> sysResources = userService.getRoleResourcese(r.getRoleId());
            log.info("用户 :权限:[{}] 进行权限认证 !", sysResources.stream().map(it -> it.getCode()).collect(Collectors.toList()));
            for (SysResource re : sysResources) {
                permissions.add(re.getCode());
            }
        }
        info.addRoles(roles);
        info.addStringPermissions(permissions);

        return info;
    }

    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authcToken) throws AuthenticationException {
        List<Map<String, Object>> menus = null;
        UsernamePasswordToken token = (UsernamePasswordToken) authcToken;
        //SysUser user = userService.getUserByName(token.getUsername());
        
        String password = String.valueOf(token.getPassword());
        String client=token.getHost()==null?Project.UNKNOW.name():token.getHost();
        SysUser user=oauthService.authUsers(token.getUsername(), password, client);
        
        user.setPassword(password);
        SimpleAuthenticationInfo sai = new SimpleAuthenticationInfo(user, user.getPassword(), this.getName());
        String projectCode = stringTpl.boundValueOps(token.getUsername() + Project.class.getName()).get();
        switch (Project.valueOf(projectCode)) {
        case RAS:
            menus = sysResourceService.findResourceByUser(user, Project.RAS);
            break;
        case RMS:
            menus = sysResourceService.findResourceByUser(user, Project.RMS);
            break;
        case RAS_WEIXIN:
        case RAS_MANAGER:
            break;
        default:
            menus = sysResourceService.findResourceByUser(user, Project.RAS);
            break;
        }
        String strMenu = JacksonUtil.getJson(menus);
        stringTpl.boundValueOps(user.getAccount() + projectCode + "_menu").set(strMenu);
        return sai;
    }

}

到此为止便可以完成登录的校验

也可以使用如下注解来完成对权限按钮的校验

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值