springboot shiro

不问归期 提交于 2019-12-07 20:33:40

最近研究后端的权限管理,一般两个选择shiro和spring security,都说shiro相对简单,就先用他,后面在去研究spring security。

具体的内容介绍不多介绍了,找了两个大佬写的博客,讲的挺不错,链接贴上

https://segmentfault.com/a/1190000011918957

https://www.cnblogs.com/ll409546297/p/7815409.html

 

然后比葫芦画瓢自己写的代码也贴上来看看,相关地方都已加上注释

ShiroConfiguration文件的内容

package com.example.web.controller;

import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.HashMap;
import java.util.Map;

@Configuration
public class ShiroConfiguration {

    //将自己的验证方式加入容器
    @Bean
    public MyShiroRealm myShiroRealm() {
        MyShiroRealm myShiroRealm = new MyShiroRealm();
        return myShiroRealm;
    }

    //权限管理,配置主要是Realm的管理认证
    @Bean
    public SecurityManager securityManager() {
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        securityManager.setRealm(myShiroRealm());
        return securityManager;
    }

    //Filter工厂,设置对应的过滤条件和跳转条件
    @Bean
    public ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager) {
        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
        shiroFilterFactoryBean.setSecurityManager(securityManager);
        Map<String, String> map = new HashMap<>();
        //logout:登出的路由设定,调用会自动完成并跳转到登录页面
//        map.put("/home/logout", "logout");
        //anon:对此类路由不进行验证,login路由也不能限制
        map.put("/home/index", "anon");
        map.put("/home/login", "anon");
        //authc:对此类路由进行验证
        map.put("/**", "authc");
        shiroFilterFactoryBean.setFilterChainDefinitionMap(map);
        //登录页面的地址,没有权限的时候会自动回到此页面
//        shiroFilterFactoryBean.setLoginUrl("/home/login");
        //登录成功后跳转到页面,感觉没什么用
//        shiroFilterFactoryBean.setSuccessUrl("/home/index");
        //错误页面,认证不通过跳转
        shiroFilterFactoryBean.setUnauthorizedUrl("/error");
        return shiroFilterFactoryBean;
    }

    //加入注解的使用,不加入这个注解不生效
    @Bean
    public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager) {
        AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
        authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);
        return authorizationAttributeSourceAdvisor;
    }
}

MyShiroRealm文件内容

package com.example.web.controller;

import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;

//定义此类用于登录验证判断
public class MyShiroRealm extends AuthorizingRealm {

    //角色权限和对应权限添加
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        //获取登录用户名
        String name = (String) principalCollection.getPrimaryPrincipal();
        //查询用户名称
        return new SimpleAuthorizationInfo();
    }

    //用户认证也就是登录信息
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        //获取用户输入的账号
        String name = authenticationToken.getPrincipal().toString();
        //通过username从数据库中查找 User对象,如果找到,没找到.
        //实际项目中,这里可以根据实际情况做缓存,如果不做,Shiro自己也是有时间间隔机制,2分钟内不会重复执行该方法
        //模拟数据库查询出来的密码是0
        String pwd = "0";
        //传入数据库查询出来的数据进行验证
        //放入shiro.调用CredentialsMatcher检验密码
        SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(name, pwd, getName());
        return simpleAuthenticationInfo;
    }
}

然后是控制器也就是页面的模拟情况代码

package com.example.web.controller;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.ArrayList;
import java.util.List;

@RestController
@CrossOrigin
public class HomeController {

    @Autowired
    HomeRepository homeRepository;

    @GetMapping("/home/index")
    public String index() {
        return "默认页面,什么操作也没有";
    }

    //登录操作
    @GetMapping("/home/login")
    public String login() {
        Subject subject = SecurityUtils.getSubject();
        UsernamePasswordToken usernamePasswordToken = new UsernamePasswordToken("admin", "0");
        //进行验证,这里可以捕获异常,然后返回对应信息
        subject.login(usernamePasswordToken);
        return "登录成功";
    }

    //如果在配置哪里配置有logout就不需要此处写代码
    @GetMapping("/home/logout")
    public String logout() {
        Subject currentUser = SecurityUtils.getSubject();
        currentUser.logout();
        return "注销成功";
    }

    //有权限拦截的页面
    @GetMapping("/home/home")
    public List<Router> home() {
        List<Router> routers = new ArrayList<>();
        Router router = new Router();
        router.setPath("/index");
        router.setName("index");
        router.setComponent("components/index");
        routers.add(router);
        List<Router> routers1 = homeRepository.findAll();
        return routers;
    }

}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!