Shiro配置

配置shiro

@Configuration
public class ShiroConfig {

    @Bean(name="myRealm")
    public Realm myRealm(){
        return new ShiroRealm();
    }

    @Bean(name="webSecurityManager")
    public DefaultWebSecurityManager webSecurityManager(){
        DefaultWebSecurityManager manager = new DefaultWebSecurityManager();
        manager.setRealm(myRealm());
        return manager;
    }

    @Bean(name="shiroFilter") //name不配置时默认使用方法名
    public ShiroFilterFactoryBean shiroFilter(){
        ShiroFilterFactoryBean shiroFilter = new ShiroFilterFactoryBean();
        shiroFilter.setSecurityManager(webSecurityManager());
        shiroFilter.setLoginUrl("/system/login");
        shiroFilter.setSuccessUrl("/index");
        shiroFilter.setUnauthorizedUrl("/system/login?type=1");

        //DefaultFilterChainManager 默认的拦截器管理  会添加DefaultFilter中默认的拦截器
        //以前新增的自定义拦截器会添加到DefaultFilterChainManager中
        Map<String,Filter> filters = new LinkedHashMap<>();
        filters.put("api",new Interceptor());
        shiroFilter.setFilters(filters);

        Map<String,String> def = new LinkedHashMap<>();//必须使用LinkedHashMap。。。按顺序的权限排列
        def.put("/common/**","anon");
        def.put("/api/**","api");//自定义的拦截器匹配
        def.put("/page/**","anon");
        def.put("/accessToken/**","anon");
        def.put("/system/logout","logout");
        def.put("/system/login*","anon");
        def.put("/**","user");//user表示认证通过或者通过记住我登录都能操作
        shiroFilter.setFilterChainDefinitionMap(def);
        return shiroFilter;
    }

    @Bean
    public AuthorizationAttributeSourceAdvisor openShiroAnnotation(){//开启shiro注解
        /*权限注解
        表示当前 Subject 已经通过 login 进行了身份验证;即 Subject. isAuthenticated()返回 true。
        表示当前 Subject 已经身份验证或者通过记住我登录的。
        表示当前 Subject 没有身份验证或通过记住我登录过,即是游客身份。
        表示当前 Subject 需要角色 admin 和 user。
        表示当前 Subject 需要权限 user:a 或 user:b。
        @RequiresAuthentication
        @RequiresUser
        @RequiresGuest
        @RequiresRoles(value={“admin”, “user”}, logical= Logical.AND)
        @RequiresPermissions (value={“user:a”, “user:b”}, logical= Logical.OR*/

        AuthorizationAttributeSourceAdvisor attr  = new AuthorizationAttributeSourceAdvisor();
        attr.setSecurityManager(webSecurityManager());
        return attr;
    }
}

自定义的Filter(//如果使用WebMvcConfigurerAdapter的addInterceptors来实现拦截,如果shiro判断为anno的类型,此时不会再执行定义的addInterceptors拦截器)

public class Interceptor extends AdviceFilter {//AdviceFilter 提供类似springmvc aop的功能,即拦截器
    @Override
    protected boolean preHandle(ServletRequest req, ServletResponse response) throws Exception {
        //进行额外的拦截操作
        return true;
    }
}

shiro需要自己编写realm来实现权限的初始化

public class ShiroRealm extends AuthorizingRealm {

    @Resource
    AdminUserService userService;

    @Resource
    ResourceService resourceService;

    /*
     * 登录信息和用户验证信息验证(non-Javadoc)
     * subject.login时执行
     * @see
     * org.apache.shiro.realm.AuthenticatingRealm#doGetAuthenticationInfo(org.
     * apache.shiro.authc.AuthenticationToken)
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        String loginId = (String) token.getPrincipal(); // 得到用户名
        String password = new String((char[]) token.getCredentials()); // 得到密码

        Adminuser user = userService.login(loginId);
        if(user == null) throw new UnknownAccountException("用户不存在");
        if(!user.getPwd().equals(password)) throw new IncorrectCredentialsException("用户名或密码错误");
        if(user.getLockStatus().equals(Constant.BOOLEAN_TRUE)) throw new LockedAccountException("用户被禁用"); 

        List<Set<Resources>> result = userService.findMenus(user);
        if(result == null || result.isEmpty()) throw new UnknownAccountException("权限不足"); 

        ActiveUser activeUser = new ActiveUser(user.getId(), user.getUsername(), result.get(0),result.get(1));

        this.setSession(Constant.SESSION_ADMINUSER, user);

        return new SimpleAuthenticationInfo(activeUser, password, getName());
    }

    /*
     * 授权查询回调函数, 进行鉴权但缓存中无用户的授权信息时调用,负责在应用程序中决定用户的访问控制的方法
     */
    @SuppressWarnings("unchecked")
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        // 获取身份信息
        /*ActiveUser user = (ActiveUser) principals.getPrimaryPrincipal();
        String uid = user.getUserId();
        Set<String> permissions = userService.findPermission(uid);*/
        Adminuser user = (Adminuser) this.getSession(Constant.SESSION_ADMINUSER);

        String key = "shiro_permission_"+user.getId();
        Set<String> permissions = null;
        Object res = Memcached.get(key);
        if(res == null){
            permissions = userService.findPermission(user);
            Memcached.put(key, permissions);
            System.err.println("数据库加载====================");
        }
        else{
            permissions = (Set<String>) res;
            System.err.println("缓存获取");
        }
        SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
        simpleAuthorizationInfo.addStringPermissions(permissions);
        return simpleAuthorizationInfo;
    }
}

登录表单提交数据

public ModelAndView login(HttpServletRequest req, @RequestParam(required=true)String loginId,@RequestParam(required=true)String password,String returnUrl,RedirectAttributes rAttr){
        ModelAndView view = new ModelAndView("redirect:/system/login");
        Subject subject = SecurityUtils.getSubject(); 
        UsernamePasswordToken token = new UsernamePasswordToken(loginId, password); 
        try { 
            //token.setRememberMe(true);//记住我
            subject.login(token); 
            if(subject.isAuthenticated())
                view.setViewName("redirect:/index");
        } catch (AuthenticationException e) { 
            rAttr.addFlashAttribute("tips",e.getMessage());
        }
        return view;
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值