• SpringBoot 整合Shiro


    pom文件, springboot 2.x

            <!--shiro-->
            <dependency>
                <groupId>org.apache.shiro</groupId>
                <artifactId>shiro-spring</artifactId>
                <version>1.4.0</version>
            </dependency>
    

    ShiroConfig.java

    package com.example.shiro.config;
    
    import com.example.shiro.realm.UserRealm;
    import org.apache.shiro.mgt.SecurityManager;
    import org.apache.shiro.spring.LifecycleBeanPostProcessor;
    import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
    import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
    import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
    import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.context.annotation.DependsOn;
    
    import javax.servlet.Filter;
    import java.util.LinkedHashMap;
    import java.util.Map;
    
    /**
     * @Title: ShiroConfig
     * @ProjectName shiro
     * @date 2019/8/29:25
     */
    @Configuration
    public class ShiroConfig {
    
        @Value("${shiro.user.loginUrl}")
        public String loginUrl;
        @Value("${shiro.user.unauthorizedUrl}")
        private String unanthorizedUrl;
        /**
         * shiro 过滤器
         * @param securityManager
         * @return
         */
        @Bean
        public ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager) {
            ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
            // Shiro的核心安全接口,这个属性是必须的
            shiroFilterFactoryBean.setSecurityManager(securityManager);
            // 身份认证失败,则跳转到登录页面的配置
            shiroFilterFactoryBean.setLoginUrl(loginUrl);
            // 权限认证失败,则跳转到指定页面
            shiroFilterFactoryBean.setUnauthorizedUrl(unanthorizedUrl);
            // Shiro连接约束配置,即过滤链的定义,所有url都必须认证通过才可以访问; anon:所有url都都可以匿名访
            LinkedHashMap<String, String> filterChainDefinitionMap = new LinkedHashMap<>();
            // 对静态资源设置匿名访问
            filterChainDefinitionMap.put("/favicon.ico**", "anon");
            filterChainDefinitionMap.put("/sy.png**", "anon");
            filterChainDefinitionMap.put("/css/**", "anon");
            filterChainDefinitionMap.put("/docs/**", "anon");
            filterChainDefinitionMap.put("/fonts/**", "anon");
            filterChainDefinitionMap.put("/img/**", "anon");
            filterChainDefinitionMap.put("/ajax/**", "anon");
            filterChainDefinitionMap.put("/js/**", "anon");
            filterChainDefinitionMap.put("/sy/**", "anon");
            filterChainDefinitionMap.put("/druid/**", "anon");
            filterChainDefinitionMap.put("/captcha/captchaImage**", "anon");
            filterChainDefinitionMap.put("/logout", "logout");
    //        filterChainDefinitionMap.put("/login", "anon,captchaValidate");
            filterChainDefinitionMap.put("/login", "anon");
            filterChainDefinitionMap.put("/index", "anon");
            // 定义filter
            Map<String, Filter> filters = new LinkedHashMap<String, Filter>();
    //        filters.put("onlineSession", onlineSessionFilter());
    //        filters.put("syncOnlineSession", syncOnlineSessionFilter());
    //        filters.put("captchaValidate", captchaValidateFilter());
    //        filters.put("kickout", kickoutSessionFilter());
            // 注销成功,则跳转到指定页面
    //        filters.put("logout", logoutFilter());
            shiroFilterFactoryBean.setFilters(filters);
            // 所有请求需要认证
            filterChainDefinitionMap.put("/**", "user"); // user 登陆过
    //        filterChainDefinitionMap.put("/**", "user,kickout,onlineSession,syncOnlineSession");
            shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
            return shiroFilterFactoryBean;
        }
    
        @Bean
        public SecurityManager securityManager(UserRealm userRealm) {
            DefaultWebSecurityManager defaultWebSecurityManager = new DefaultWebSecurityManager();
            defaultWebSecurityManager.setRealm(userRealm);
            // 记住我
    //        securityManager.setRememberMeManager(rememberMeManager());
            // 注入缓存管理器;
    //        securityManager.setCacheManager(getEhCacheManager());
            // session管理器
    //        securityManager.setSessionManager(sessionManager());
            return defaultWebSecurityManager;
        }
    
        /**
         * 自定义Realm
         * EhCacheManager cacheManager
         */
        @Bean
        public UserRealm userRealm()
        {
            UserRealm userRealm = new UserRealm();
    //        userRealm.setCacheManager(cacheManager);
            return userRealm;
        }
    
        /**
         * 开启Shiro注解通知器, 不然使用注解失效
         */
        @Bean
        public LifecycleBeanPostProcessor lifecycleBeanPostProcessor(){
            return new LifecycleBeanPostProcessor();
        }
        @Bean
        @DependsOn({"lifecycleBeanPostProcessor"})
        public DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator(){
            DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator = new DefaultAdvisorAutoProxyCreator();
            advisorAutoProxyCreator.setProxyTargetClass(true);
            return advisorAutoProxyCreator;
        }
        @Bean
        public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager){
            AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
            authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);
            return authorizationAttributeSourceAdvisor;
        }
    }
    

     

    自定义Realm

    package com.example.shiro.realm;
    
    import org.apache.shiro.SecurityUtils;
    import org.apache.shiro.authc.*;
    import org.apache.shiro.authz.AuthorizationInfo;
    import org.apache.shiro.authz.SimpleAuthorizationInfo;
    import org.apache.shiro.realm.AuthorizingRealm;
    import org.apache.shiro.subject.PrincipalCollection;
    
    import java.util.HashSet;
    import java.util.Set;
    
    /**
     * @Title: UserRealm
     * @ProjectName shiro
     * @date 2019/8/29:27
     */
    public class UserRealm extends AuthorizingRealm {
        /**
         * 授权
         * @param principalCollection
         * @return
         */
        @Override
        protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
            String username = (String) SecurityUtils.getSubject().getPrincipal();
            SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
            Set<String> stringSet = new HashSet<>();
            stringSet.add("user:view:add");
            stringSet.add("user:view:del");
            Set<String> role = new HashSet<>();
            role.add("admin");
            info.setRoles(role); // set 角色
            info.setStringPermissions(stringSet);  // set 权限
            return info;
        }
    
        /**
         * 每次登陆都会进入此方法,认证
         * @param token
         * @return
         * @throws AuthenticationException
         */
        @Override
        protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
            System.out.println("-------身份认证方法--------");
            UsernamePasswordToken upToken = (UsernamePasswordToken) token;
    
            String userName = upToken.getUsername();
            String userPwd = upToken.getPassword() != null ? new String(upToken.getPassword()) : "";
            //根据用户名从数据库获取密码进行对比
            String password = "123qwe";
            if (userName == null) {
                throw new AccountException("用户名不正确");
            } else if (!userPwd.equals(password)) {
                throw new AccountException("密码不正确");
            }
            return new SimpleAuthenticationInfo(userName, password, getName());
        }
    }
    

      设置

    // 权限认证失败,则跳转到指定页面
            shiroFilterFactoryBean.setUnauthorizedUrl(unanthorizedUrl);
    

      设置跳转页面失败,报错情况增加异常处理即可.

    package com.example.shiro.advice;
    
    import org.apache.shiro.authz.AuthorizationException;
    import org.apache.shiro.authz.UnauthorizedException;
    import org.springframework.web.bind.annotation.ControllerAdvice;
    import org.springframework.web.bind.annotation.ExceptionHandler;
    import org.springframework.web.bind.annotation.ResponseBody;
    
    import javax.servlet.http.HttpServletRequest;
    
    /**
     * @Title: NoPermissionException
     * @ProjectName shiro
     * @date 2019/8/211:20
     */
    @ControllerAdvice
    public class NoPermissionException {
    
        @ResponseBody
        @ExceptionHandler(UnauthorizedException.class)
        public String handleShiroException(HttpServletRequest request,UnauthorizedException ex) {
            return "无权限";
        }
        @ResponseBody
        @ExceptionHandler(AuthorizationException.class)
        public String AuthorizationException(HttpServletRequest request, AuthorizationException e) {
            return "权限认证失败";
        }
    }
    

      

    Controller

    package com.example.shiro.controller;
    
    import org.apache.shiro.SecurityUtils;
    import org.apache.shiro.authc.UsernamePasswordToken;
    import org.apache.shiro.authz.annotation.RequiresPermissions;
    import org.apache.shiro.authz.annotation.RequiresRoles;
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.PostMapping;
    import org.springframework.web.bind.annotation.ResponseBody;
    
    
    /**
     * @Title: ShiroController
     * @ProjectName shiro
     * @date 2019/8/210:20
     */
    @Controller
    public class ShiroController {
        @ResponseBody
        @GetMapping("login")
        public String login() {
            return "LOGIN";
        }
    
        @ResponseBody
        @PostMapping("login")
        public String postLogin(String username,String password) {
            org.apache.shiro.subject.Subject subject = SecurityUtils.getSubject();
            UsernamePasswordToken token = new UsernamePasswordToken(username,password);
            try {
                subject.login(token);
            } catch (Exception e) {
                return "登陆失败";
            }
            return "登陆成功";
    
    
        }
        @ResponseBody
        @RequiresPermissions("user:view:add")
        @GetMapping("add")
        public String add() {
            return "add";
        }
        @ResponseBody
        @RequiresPermissions("user:view:del")
        @GetMapping("del")
        public String del() {
            return "del";
        }
    
        @ResponseBody
        @GetMapping("userupdate")
        @RequiresRoles(value = "user")
        public String userupdate() {
            return "userupdate";
        }
    
        @ResponseBody
        @GetMapping("viewselect")
        @RequiresPermissions("xxx:xxx:xxx")
        public String select()
        {
            return "select";
        }
    
        @ResponseBody
        @RequiresRoles(value = "admin")
        @GetMapping("update")
        public String update() {
            return "update";
        }
        @ResponseBody
        @GetMapping("unauth")
        public String unauth() {
            return "unauth 504 没有权限";
        }
        @ResponseBody
        @GetMapping("loginout")
        public String loginOut() {
            SecurityUtils.getSubject().logout();
            return "loginout";
        }
    
        @GetMapping("index")
        public String index(){
            return "index";
        }
    }
    

      

     

      

  • 相关阅读:
    css常用字体
    多行文本显示省略号,点击展开隐藏
    某个公司采用公用电话传递数据,数据是四位的整数,在传递过程中是加密的, 加密规则如下:每位数字都加上5,然后用除以10的余数代替该数字,再将第一位和第四位交换, 第二位和第三位交换,请编写一个函数,传入原文,输出密文
    编写一个函数,计算任意两个数字之间所能组成的奇数个数,数字必须是个位数。 比如:计算0~3之间能组成的奇数是: 01、03、13、21、23、31
    Redis(一) 数据结构与底层存储 & 事务 & 持久化 & lua
    IO多路复用之Reactor
    IO多路复用之select poll epoll
    五种IO模型
    kafka(五) 流式处理 kafka stream
    kafka(二) 高性能技术分析
  • 原文地址:https://www.cnblogs.com/412013cl/p/11288766.html
Copyright © 2020-2023  润新知