最近研究后端的权限管理,一般两个选择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