当前位置 主页 > 服务器问题 > Linux/apache问题 >

    基于springboot实现整合shiro实现登录认证以及授权过程解析

    栏目:Linux/apache问题 时间:2019-12-19 22:42

    这篇文章主要介绍了基于springboot实现整合shiro实现登录认证以及授权过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下

    1.添加shiro的依赖

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

    2.先创建一个Realm

    public class MyShiroRealm extends AuthorizingRealm {
      @Autowired
      private RoleService roleService;//角色模模块
      @Autowired
      private UserService userService;//用户模块
      @Autowired
      private PermissionService permissionService;//权限模块
      /**
       * 用户身份识别(登录")
       * @param authenticationToken
       * @return
       * @throws AuthenticationException
       */
      @Override
      protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        UsernamePasswordToken authToken = (UsernamePasswordToken) authenticationToken;
        // 获取用户输入的账号
        String userName = authToken.getUsername();
         //通过账号查找用户信息
        User user= userService.selectUserOne(userName);// 将账户名,密码,盐值,getName()实例化到SimpleAuthenticationInfo中交给Shiro来管理
        SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(
                                  user,
                                  user.getPassWord(),
                                        //这里是设置的密码盐
                                  ByteSource.Util.bytes(user.getSalt()),
                                  getName());
        return authenticationInfo;
      }
    
      /**
       * 访问控制。比如某个用户是否具有某个操作的使用权限
       * @param principalCollection
       * @return
       */
      @Override
      protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
        String userName = (String) principalCollection.getPrimaryPrincipal();
        if (userName == null) {
          log.error("授权失败,用户信息为空!!!");
          return null;
        }
        try {
          //获取用户角色集
          Set<String> listRole= roleService.findRoleByUsername(userName);
          simpleAuthorizationInfo.addRoles(listRole);
          //通过角色获取权限集
          for (String role : listRole) {
            Set<String> permission= permissionService.findPermissionByRole(role);
            simpleAuthorizationInfo.addStringPermissions(permission);
          }
          return simpleAuthorizationInfo;
        } catch (Exception e) {
          log.error("授权失败,请检查系统内部错误!!!", e);
        }
        return simpleAuthorizationInfo;
      }
    }


    3.创建shiro的配置类

    @Configuration
    public class ShiroConfiguration {
       //配置自定义的Realm
      @Bean
      public MyShiroRealm myShiroRealm(HashedCredentialsMatcher matcher){
        MyShiroRealm myShiroRealm= new MyShiroRealm();
         //在这里配置密码加密
        myShiroRealm.setCredentialsMatcher(matcher);
        return myShiroRealm;
      }
    
       //将Realm注册到securityManager中
      @Bean
      public DefaultWebSecurityManager securityManager(HashedCredentialsMatcher matcher){
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        securityManager.setRealm(myShiroRealm(matcher));
        return securityManager;
      }
    
      //如果没有此name,将会找不到shiroFilter的Bean
      @Bean(name = "shiroFilter")
      public ShiroFilterFactoryBean shiroFilter(org.apache.shiro.mgt.SecurityManager securityManager){
        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
        shiroFilterFactoryBean.setSecurityManager(securityManager);
        shiroFilterFactoryBean.setLoginUrl("/login");     //表示指定登录页面
        shiroFilterFactoryBean.setSuccessUrl("/user/list");  // 登录成功后要跳转的链接
        shiroFilterFactoryBean.setUnauthorizedUrl("/403");  //未授权页面
    
        Map<String,String> filterChainDefinitionMap = new LinkedHashMap<>();//拦截器, 配置不会被拦截的链接 顺序判断
        filterChainDefinitionMap.put("/login","anon");           //所有匿名用户均可访问到Controller层的该方法下
        filterChainDefinitionMap.put("/userLogin","anon");
        filterChainDefinitionMap.put("/image/**","anon");
        filterChainDefinitionMap.put("/css/**", "anon");
        filterChainDefinitionMap.put("/fonts/**","anon");
        filterChainDefinitionMap.put("/js/**","anon");
        filterChainDefinitionMap.put("/logout","logout");
        filterChainDefinitionMap.put("/**", "authc"); //authc:所有url都必须认证通过才可以访问; anon:所有url都都可以匿名访问
        //filterChainDefinitionMap.put("/**", "user");    //user表示配置记住我或认证通过可以访问的地址
        shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
        return shiroFilterFactoryBean;
      }
    
      /**
       * SpringShiroFilter首先注册到spring容器
       * 然后被包装成FilterRegistrationBean
       * 最后通过FilterRegistrationBean注册到servlet容器
       * @return
       */
      @Bean
      public FilterRegistrationBean delegatingFilterProxy(){
        FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean();
        DelegatingFilterProxy proxy = new DelegatingFilterProxy();
        proxy.setTargetFilterLifecycle(true);
        proxy.setTargetBeanName("shiroFilter");
        filterRegistrationBean.setFilter(proxy);
        return filterRegistrationBean;
      }
      //设置cookie
      @Bean
      public SimpleCookie rememberMeCookie(){
        //这个参数是cookie的名称,对应前端的checkbox的name=rememberMe
        SimpleCookie simpleCookie = new SimpleCookie("rememberMe");
        //记住我cookie生效时间3个小时(单位秒)
        simpleCookie.setMaxAge(10800);
        return simpleCookie;
      }
      //cookie管理对象,记住我功能
      @Bean
      public CookieRememberMeManager rememberMeManager(){
        CookieRememberMeManager cookieRememberMeManager = new CookieRememberMeManager();
        cookieRememberMeManager.setCookie(rememberMeCookie());
        return cookieRememberMeManager;
      }
      /**
       * 密码匹配凭证管理器(密码加密需要此配置)
       * @return
       */
      @Bean(name = "hashedCredentialsMatcher")
      public HashedCredentialsMatcher hashedCredentialsMatcher() {
        HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher();
        hashedCredentialsMatcher.setHashAlgorithmName("MD5");
        hashedCredentialsMatcher.setHashIterations(1024);// 设置加密次数
        return hashedCredentialsMatcher;
      }
      //如果没有这两个配置,可能会授权失败,所以依赖中还需要配置aop的依赖
      @Bean
      public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(HashedCredentialsMatcher matcher) {
        AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
        authorizationAttributeSourceAdvisor.setSecurityManager(securityManager(matcher));
        return authorizationAttributeSourceAdvisor;
      }
      @Bean
      @ConditionalOnMissingBean
      public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator(){
        DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator=new DefaultAdvisorAutoProxyCreator();
        defaultAdvisorAutoProxyCreator.setProxyTargetClass(true);
        return defaultAdvisorAutoProxyCreator;
      }
    }