zoukankan      html  css  js  c++  java
  • (二) shiro集成 --《springboot与shiro整合》

    2.1 引入shiro相关依赖

         <dependency>  
                <groupId>commons-logging</groupId>  
                <artifactId>commons-logging</artifactId>  
                <version>1.1.3</version>  
            </dependency>  
            <dependency>  
                <groupId>org.apache.shiro</groupId>  
                <artifactId>shiro-core</artifactId>  
                <version>1.2.2</version>  
            </dependency>  
             <dependency>  
                <groupId>org.apache.shiro</groupId>  
                <artifactId>shiro-web</artifactId>  
                <version>1.2.2</version>  
            </dependency>   

    2.2  自定义Realm  

    @Component
    public class UserRealm extends AuthorizingRealm{
        
        
        @Autowired
        private UserService userService;
        
        /**
         * 授权
         * @param principals
         * @return
         */
        @Override
        protected AuthorizationInfo doGetAuthorizationInfo(
                PrincipalCollection principals) {
            
            String username = (String) principals.getPrimaryPrincipal();
            SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
            //在数据库中查询用户拥有的角色/权限
            authorizationInfo.setRoles(userService.findRoles(username));
            authorizationInfo.setStringPermissions(userService.findPermissions(username));
            return authorizationInfo;
        }
    
        
        /**
         * 验证
         */
        @Override
        protected AuthenticationInfo doGetAuthenticationInfo(
                AuthenticationToken token) throws AuthenticationException {
    
            String username = (String) token.getPrincipal();
            User user = userService.findByUsername(username); 
            if(user == null){
                throw new UnknownAccountException(); //没找到账号
            }
            
            if(Boolean.TRUE.equals(user.getLocked())){
                throw new LockedAccountException(); //账号被锁定
            }
            
            SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(
                    user.getUsername(),
                    user.getPassword(),
                    ByteSource.Util.bytes(user.getCredentialsSalt()), //salt = username+salt
                    getName());
                
            
            return authenticationInfo;
        }
    
    }

    2.3 ShiroConfig 

    @Configuration
    public class ShiroConfig {
        
        @Bean  
        public ShiroFilterFactoryBean shiroFilter(SecurityManager securityManager){
            ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
            shiroFilterFactoryBean.setSecurityManager(securityManager);
            //拦截器.  
            Map<String,String> filterChainDefinitionMap = new LinkedHashMap<String,String>(); 
            //配置退出过滤器,其中的具体的退出代码Shiro已经替我们实现了  
            filterChainDefinitionMap.put("logout", "logout");
            filterChainDefinitionMap.put("/user/login", "anon");
            // authc:所有url都必须认证通过才可以访问; anon:所有url都都可以匿名访问
            filterChainDefinitionMap.put("/user/**", "anon");
    filterChainDefinitionMap.put("/test/**", "authc");
    filterChainDefinitionMap.put("/page/**", "authc"); // 如果不设置默认会自动寻找Web工程根目录下的"/login.jsp"页面 shiroFilterFactoryBean.setLoginUrl("/login.html");
            shiroFilterFactoryBean.setUnauthorizedUrl("/page/fail.html");//未授权跳转
            //登录成功跳转的链接 (这个不知道怎么用,我都是自己实现跳转的)
            shiroFilterFactoryBean.setSuccessUrl("/page/main.html");
            shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
            return shiroFilterFactoryBean;
        }
        
        /**  
         * 凭证匹配器  
         * 由于我们的密码校验交给Shiro的SimpleAuthenticationInfo进行处理了  
         * @return  
         */  
        @Bean  
        public HashedCredentialsMatcher hashedCredentialsMatcher() {  
            HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher();  
            hashedCredentialsMatcher.setHashAlgorithmName("md5");//散列算法:这里使用MD5算法;  
            hashedCredentialsMatcher.setHashIterations(2);//散列的次数,比如散列两次,相当于 md5(md5(""));  
            return hashedCredentialsMatcher;  
        }  
        
        
        @Bean  
        public UserRealm myShiroRealm() {  
            UserRealm myShiroRealm = new UserRealm(); 
    //使用加密
    myShiroRealm.setCredentialsMatcher(hashedCredentialsMatcher());
            return myShiroRealm;  
        }  
        
        @Bean  
        public SecurityManager securityManager() {  
            DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();  
            securityManager.setRealm(myShiroRealm());  
            return securityManager;  
        }
        
        
        @Bean
        public LifecycleBeanPostProcessor lifecycleBeanPostProcessor(){
            return new LifecycleBeanPostProcessor();
        }
        
        /** 
         * 注册全局异常处理 
         * @return 
         */  
        @Bean(name = "exceptionHandler")  
        public HandlerExceptionResolver handlerExceptionResolver() {  
            return new ExceptionHandler();  
        }
        
        
    }

    2.4 创建UserController

    @RestController
    @RequestMapping("/user")
    public class UserController {
        
        @Autowired
        private UserService userService;
        
        @RequestMapping("/login")
        public ModelAndView login(User loginUser,ServletRequest request){
            
            ModelAndView view = new ModelAndView();
            Subject subject = SecurityUtils.getSubject();
            UsernamePasswordToken token = new UsernamePasswordToken(loginUser.getUsername(),loginUser.getPassword());
            if(!subject.isAuthenticated()){
                
                subject.login(token);
            }
            //获取上一次请求路径
            SavedRequest savedRequest = WebUtils.getSavedRequest(request);
            String url = "";
            if(savedRequest != null){
                url = savedRequest.getRequestUrl();
            }else{
                url = "/page/main.html";
            }
            
            view.setViewName("redirect:"+url);
            return view;
        }
        
        @RequestMapping("/register")
        public ModelAndView add(User user){
            ModelAndView view = new ModelAndView();
            userService.createUser(user);
            view.setViewName("redirect:/login.html");
            return view;
        }
        
        @RequestMapping("/logout")
        public String logout(User loginUser){
            Subject subject = SecurityUtils.getSubject();
            subject.logout();
            return "已注销";
        }
    }

    UserService

        @Override
        public Long createUser(User user) {
            PasswordHelper.encryptPassword(user);
            return userDao.createUser(user);
        }

    PasswordHelper (加密,保存到数据库的时候使用)

        private static RandomNumberGenerator randomNumberGenerator = new SecureRandomNumberGenerator();
        //这些要与Realm中的一致
        private static String algorithmName = "md5";
        private final static int hashIterations = 2;
    
        static public  void encryptPassword(User user) {
            //加盐
            user.setSalt(randomNumberGenerator.nextBytes().toHex());
            String newPassword = new SimpleHash(algorithmName, user.getPassword(),
                    ByteSource.Util.bytes(user.getCredentialsSalt()),
                    hashIterations).toHex();
            user.setPassword(newPassword);
        }

    下面我们来测试一下吧 (页面代码这里就不写了)

    我们先访问  http://localhost:8080/page/main.html  由于在ShiroConfig中设置了 page 目录下面的所有文件都需要认真通过才能访问

     filterChainDefinitionMap.put("/page/**", "authc"); 

    这时候会跳转到登录页面

    先注册一个用户

    查看数据库

     这时候在登录就可以访问到首页了

    很简单的一个用户认证功能,下面我们继续完善

    源码点这里

  • 相关阅读:
    第二阶段团队站立会议06
    第二阶段团队站立会议05
    Spring
    JVM
    线程池
    java内存模型
    线程
    接口与抽象类
    动态绑定,多态,static
    同步异步,并发并行概念的理解
  • 原文地址:https://www.cnblogs.com/zls1218/p/8780178.html
Copyright © 2011-2022 走看看