最近研究后端的权限管理,一般两个选择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;
}
}
来源:oschina
链接:https://my.oschina.net/u/3031369/blog/3043336