shiro原理/流程(前后端不分离)

1.整体流程

  1》subject 封装了用户名密码,用户权限,用户角色等信息

  2》securitymanager负责进行校验用户名密码,权限等操作

  3》realm,相当于securitymanager的数据源,去数据库查询,将权限,是否登录成功等信息提供给secutirymanager

流程如图

2.前后端不分离,代码实现

需要自定义realm   shiro配置类

1》shiro配置类

  配置securitymanager 使用自定义realm

  配置默认的ShiroFilterFactoryBean  设置拦截路径和权限 

package com.example.shiro78.config;

import at.pollux.thymeleaf.shiro.dialect.ShiroDialect;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.cache.ehcache.EhCacheManager;
import org.apache.shiro.mgt.DefaultSecurityManager;
import org.apache.shiro.realm.jdbc.JdbcRealm;
import org.apache.shiro.realm.text.IniRealm;
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.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.sql.DataSource;
import java.util.HashMap;
import java.util.Map;

@Configuration
public class ShiroConfig {
    @Autowired
    MyRealm myRealm;

    public MyRealm getmyrealm() {
//        myRealm.setCredentialsMatcher(getCredentialsMatcher());
        return myRealm;
    }

//    @Bean
//    public HashedCredentialsMatcher getCredentialsMatcher() {
        用来指定加密规则
//        HashedCredentialsMatcher matcher = new HashedCredentialsMatcher();
//        matcher.setHashAlgorithmName("MD5");
//        matcher.setHashIterations(1);
//        return matcher;
//    }

    //配置thmymeleaf方言
    @Bean
    public ShiroDialect getshirodialect() {
        return new ShiroDialect();
    }

    //    创建securitymanager
    @Bean
    public DefaultWebSecurityManager getdefaultWebSecurityManager() {
        DefaultWebSecurityManager defaultWebSecurityManager = new DefaultWebSecurityManager();
//        defaultWebSecurityManager.setCacheManager(getehacche());
        defaultWebSecurityManager.setRealm(getmyrealm());
        return defaultWebSecurityManager;
    }

    //    设置拦截器,作用是设定什么路径需要什么样的权限(未登录可访问的路径,登录后可访问的路径)
    @Bean
    public ShiroFilterFactoryBean shiroFilter(DefaultSecurityManager defaultSecurityManager) {
        ShiroFilterFactoryBean filter = new ShiroFilterFactoryBean();
        filter.setSecurityManager(defaultSecurityManager);
        Map<String, String> filtermap = new HashMap<>();
//        anon匿名用户可以访问
//        authc 认证用户可以访问

//        user 使用rememberme的用户可以访问
//        perms 对应权限可以访问
//        role 对应的角色可以访问
//        注意注意!!!! 这里只是拦截的路径,还需要写控制器让路径对应页面
        filtermap.put("/", "anon");
        filtermap.put("/login", "anon");
        filtermap.put("/login.html", "anon");
        filtermap.put("/user/login", "anon");
        filtermap.put("/index.html", "anon");
//        filtermap.put("/dingdan/add", "anon");
        filtermap.put("/user/regist", "authc");
        filtermap.put("/regist", "anon");
        filtermap.put("/static/**", "anon");
        filtermap.put("/norenzheng", "anon");
//        新增订单权限
        filtermap.put("/dingdan/add", "perms[sys:x:save]");
        filtermap.put("/norenzheng.html", "anon");
        filtermap.put("/exit", "logout");
        filter.setFilterChainDefinitionMap(filtermap);
//        当访问autch的页面时,未登录,跳转的页面
        filter.setLoginUrl("/nologin");
//        当访问需要具体权限时,未登录,或者权限不足时跳转的页面
        filter.setUnauthorizedUrl("/norenzhenghuobuzu");
        return filter;
    }

    //配置注解管理权限 ,记住就好
    @Bean
    public AuthorizationAttributeSourceAdvisor getAuthorizationAttributeSourceAdvisor() {
        AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
        authorizationAttributeSourceAdvisor.setSecurityManager(getdefaultWebSecurityManager());
        return authorizationAttributeSourceAdvisor;
    }

    @Bean
    public DefaultAdvisorAutoProxyCreator getDefaultAdvisorAutoProxyCreator() {
        DefaultAdvisorAutoProxyCreator autoproxycreator = new DefaultAdvisorAutoProxyCreator();
        autoproxycreator.setProxyTargetClass(true);
        return autoproxycreator;
    }

//    // 配置缓存管理  避免进行多次对数据库的查询
//    @Bean
//    public EhCacheManager getehacche() {
//        EhCacheManager ehCacheManager = new EhCacheManager();
//        ehCacheManager.setCacheManagerConfigFile("classpath:ehcache.xml");
//        return ehCacheManager;
//    }

    @Autowired
    DataSource dataSource;

//    public JdbcRealm getjdbcrealm() {
//        JdbcRealm jdbcRealm = new JdbcRealm();
//        jdbcRealm.setDataSource(dataSource);
//        return jdbcRealm;
//    }
//
//    public IniRealm getiniRealm() {
//        IniRealm iniRealm = new IniRealm("E:\\java\\shiro\\shiro7.8\\src\\main\\resources\\Shiro.ini");
//        return iniRealm;
//    }


}

2》配置自定义realm

重写认证方法和查询权限角色方法

package com.example.shiro78.config;

import com.example.shiro78.dao.UserMapper;
import com.example.shiro78.pojo.User;
import com.example.shiro78.service.Checklogin;
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 org.apache.shiro.util.ByteSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;
import java.util.Set;

@Service
public class MyRealm extends AuthorizingRealm {
    @Autowired
    UserMapper userMapper;

    public String getrealmname() {
        return "MyRealm1";
    }

    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
//        获取当前已经登录用户的用户名
        String uname = (String) principalCollection.iterator().next();
        Set<String> permissions = userMapper.querypermission(uname);
        Set<String> roles = userMapper.queryrole(uname);
        SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
        simpleAuthorizationInfo.setStringPermissions(permissions);
        simpleAuthorizationInfo.setRoles(roles);
        System.out.println("角色是" + roles);
        System.out.println("权限是" + permissions);
//        将权限信息返回权限管理器
        return simpleAuthorizationInfo;
    }

    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        UsernamePasswordToken usernamePasswordToken = (UsernamePasswordToken) authenticationToken;
        String uname = usernamePasswordToken.getUsername();
        User user = userMapper.checklogin(uname);
        if (user == null) {
            return null;
        }
        AuthenticationInfo info = new SimpleAuthenticationInfo(user.getUsername(), user.getPassword(),  getrealmname());
//        将认证信息返回认证器
        return info;
    }
}

 1,2 5处的代码是 ShiroConfig 类的 ShiroFilterFactoryBean 的 filtermap.put("/...", "....");

   判断是否放行

 3处的代码是程序员自己调用的,如下

@Service
public class Checklogin {
    public void checklogin(String username,String password) throws Exception
    {
        UsernamePasswordToken usernamePasswordToken=new UsernamePasswordToken(username,password);
        Subject subject= SecurityUtils.getSubject();
        subject.login(usernamePasswordToken);
    }
}

4处的代码是在controller层添加注解

    //需要某个权限才可以访问
   @RequiresPermissions("sys:x:delete")
    @ResponseBody
    @RequestMapping("/dingdan/del")
    public String deldingdan() {
        return "具有删除订单权限";
    }
     //需要某个角色才可以访问
    @RequiresRoles("cmanager")
    @ResponseBody
    @RequestMapping("/cmanager")
    public String cmanager() {
        return "具有cmanager角色";
    }

    //  需要登录后才可以访问
    @RequiresAuthentication
    @ResponseBody
    @RequestMapping("/login")
    public String testerror() {
        return  "登录成功";
    }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值