zoukankan      html  css  js  c++  java
  • 使用Shiro实现认证和授权(基于SpringBoot)

    Apache Shiro是一个功能强大且易于使用的Java安全框架,它为开发人员提供了一种直观,全面的身份验证,授权,加密和会话管理解决方案。下面是在SpringBoot中使用Shiro进行认证和授权的例子,代码如下:

    pom.xml

    导入SpringBoot和Shiro依赖:

    <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </dependency>
    
            <dependency>
                <groupId>org.apache.shiro</groupId>
                <artifactId>shiro-spring</artifactId>
                <version>1.4.2</version>
            </dependency>
    </dependencies>
    

    也可以直接导入Apache Shiro提供的starter:

    <dependency>
            <groupId>org.apache.shiro</groupId>
            <artifactId>shiro-spring-boot-web-starter</artifactId>
    </dependency>
    

    Shiro配置类

    package com.cf.shiro1.config;
    
    import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
    import org.apache.shiro.realm.Realm;
    import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
    import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
    import org.springframework.beans.factory.annotation.Qualifier;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    
    import java.util.HashMap;
    import java.util.Map;
    
    @Configuration
    public class ShiroConfig {
    
        @Bean
        public ShiroFilterFactoryBean shiroFilterFactoryBean(@Qualifier("defaultWebSecurityManager") DefaultWebSecurityManager defaultWebSecurityManager) {
            ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
    
            //设置安全管理器
            shiroFilterFactoryBean.setSecurityManager(defaultWebSecurityManager);
    
            //设置未认证(登录)时,访问需要认证的资源时跳转的页面
            shiroFilterFactoryBean.setLoginUrl("/loginPage");
    
            //设置访问无权限的资源时跳转的页面
            shiroFilterFactoryBean.setUnauthorizedUrl("/unauthorizedPage");
            
            //指定路径和过滤器的对应关系
            Map<String, String> filterMap = new HashMap<>();
            //设置/user/login不需要登录就能访问
            filterMap.put("/user/login", "anon");
            //设置/user/list需要登录用户拥有角色user时才能访问
            filterMap.put("/user/list", "roles[user]");
            //其他路径则需要登录才能访问
            filterMap.put("/**", "authc");
            shiroFilterFactoryBean.setFilterChainDefinitionMap(filterMap);
            return shiroFilterFactoryBean;
        }
    
        @Bean
        public DefaultWebSecurityManager defaultWebSecurityManager(@Qualifier("realm") Realm realm) {
            DefaultWebSecurityManager defaultWebSecurityManager = new DefaultWebSecurityManager();
            defaultWebSecurityManager.setRealm(realm);
            return defaultWebSecurityManager;
        }
    
        @Bean
        public Realm realm() {
            MyRealm realm = new MyRealm();
            //使用HashedCredentialsMatcher带加密的匹配器来替换原先明文密码匹配器
            HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher();
            //指定加密算法
            hashedCredentialsMatcher.setHashAlgorithmName("MD5");
            //指定加密次数
            hashedCredentialsMatcher.setHashIterations(3);
            realm.setCredentialsMatcher(hashedCredentialsMatcher);
            return realm;
        }
    }
    
    

    自定义Realm

    package com.cf.shiro1.config;
    
    import org.apache.shiro.authc.*;
    import org.apache.shiro.authz.AuthorizationInfo;
    import org.apache.shiro.authz.SimpleAuthorizationInfo;
    import org.apache.shiro.crypto.hash.SimpleHash;
    import org.apache.shiro.realm.AuthorizingRealm;
    import org.apache.shiro.subject.PrincipalCollection;
    import org.apache.shiro.util.ByteSource;
    
    import java.util.HashMap;
    import java.util.HashSet;
    import java.util.Map;
    import java.util.Set;
    
    public class MyRealm extends AuthorizingRealm {
        /**
         * 授权
         *
         * @param principalCollection
         * @return
         */
        @Override
        protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
            Object username = principalCollection.getPrimaryPrincipal();
            SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
            simpleAuthorizationInfo.setRoles(getRoles(username.toString()));
            return simpleAuthorizationInfo;
        }
    
        /**
         * 认证
         *
         * @param authenticationToken
         * @return
         * @throws AuthenticationException
         */
        @Override
        protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
            UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken;
    
            String username = token.getUsername();
            Map<String, Object> userInfo = getUserInfo(username);
            if (userInfo == null) {
                throw new UnknownAccountException();
            }
    
            //盐值,此处使用用户名作为盐
            ByteSource salt = ByteSource.Util.bytes(username);
    
            SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(username, userInfo.get("password"), salt, getName());
            return authenticationInfo;
        }
    
        /**
         * 模拟数据库查询,通过用户名获取用户信息
         *
         * @param username
         * @return
         */
        private Map<String, Object> getUserInfo(String username) {
            Map<String, Object> userInfo = null;
            if ("zhangsan".equals(username)) {
                userInfo = new HashMap<>();
                userInfo.put("username", "zhangsan");
    
                //加密算法,原密码,盐值,加密次数
                userInfo.put("password", new SimpleHash("MD5", "123456", username, 3));
            }
            return userInfo;
        }
    
        /**
         * 模拟查询数据库,获取用户角色列表
         *
         * @param username
         * @return
         */
        private Set<String> getRoles(String username) {
            Set<String> roles = new HashSet<>();
            roles.add("user");
            roles.add("admin");
            return roles;
        }
    }
    
    

    Controller

    package com.cf.shiro1.controller;
    
    import org.apache.shiro.SecurityUtils;
    import org.apache.shiro.authc.*;
    import org.apache.shiro.subject.Subject;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    @RestController
    @RequestMapping("/user")
    public class UserController {
    
        /**
         * 登录
         * @param username
         * @param password
         * @return
         */
        @RequestMapping("/login")
        public String userLogin(String username, String password) {
            String result;
    
            //获取当前用户
            Subject currentUser = SecurityUtils.getSubject();
    
            //用户是否已经登录,未登录则进行登录
            if (!currentUser.isAuthenticated()) {
                //封装用户输入的用户名和密码
                UsernamePasswordToken usernamePasswordToken = new UsernamePasswordToken(username, password);
    
                try {
                    //登录,进行密码比对,登录失败时将会抛出对应异常
                    currentUser.login(usernamePasswordToken);
                    result = "登录成功";
                } catch (UnknownAccountException uae) {
                    result = "用户名不存在";
                } catch (IncorrectCredentialsException ice) {
                    result = "密码错误";
                } catch (LockedAccountException lae) {
                    result = "用户状态异常";
                } catch (AuthenticationException ae) {
                    result = "登录失败,请与管理员联系";
                }
            } else {
                result = "您已经登录成功了";
            }
    
            return result;
        }
    
        @RequestMapping("/list")
        public String userList() {
            return "访问我需要登录并且需要拥有user角色!";
        }
    }
    
    
  • 相关阅读:
    压缩和还原压缩的JS代码
    1.3(Spring学习笔记)Spring-AOP
    软件配置篇-MySQL下载及安装
    软件配置篇-java下载及安装
    1.2(Spring学习笔记)Spring中的Bean
    1.1(Spring学习笔记)Spring基础(BeanFactory、ApplicationContext 、依赖注入)
    1.6(学习笔记)EL表达式
    1.5 JSP标准标签库(JSTL)(核心标签 out、set、remove、if、choose、forEach、forTokens、redirect)
    1.4(学习笔记)JSP自定义标签
    随机算式
  • 原文地址:https://www.cnblogs.com/seve/p/12241197.html
Copyright © 2011-2022 走看看