开发工具:STS
前言:
shiro,一套简单灵活的安全权限管理框架。
把所有对外暴露的服务API都看作是一种资源,那么shiro就是负责控制哪些可以获得资源,哪些不能获取。
一个比较不错的教程:
一个简单的小实例:
1.引入依赖
1 24 4.0.0 5 6com.xm 7springboot_rbac 80.0.1-SNAPSHOT 9jar 10 11springboot_rbac 12This is a Web about springcloud 13 1415 20 21org.springframework.boot 16spring-boot-starter-parent 171.5.15.RELEASE 1819 22 26 27UTF-8 23UTF-8 241.8 2528 49 5029 32 33org.springframework.boot 30spring-boot-starter-web 3134 38org.springframework.boot 35spring-boot-starter-test 36test 3739 43 44org.apache.shiro 40shiro-spring 411.2.2 4245 48org.springframework.boot 46spring-boot-starter-aop 4751 58 59 6052 5753 56org.springframework.boot 54spring-boot-maven-plugin 55
2.配置文件application.yml
1 spring.aop.proxy-target-class=true
3.realm
1 package com.xm.shiro.rbac; 2 3 import java.util.HashMap; 4 import java.util.Map; 5 6 import org.apache.shiro.authc.AccountException; 7 import org.apache.shiro.authc.AuthenticationException; 8 import org.apache.shiro.authc.AuthenticationInfo; 9 import org.apache.shiro.authc.AuthenticationToken;10 import org.apache.shiro.authc.SimpleAuthenticationInfo;11 import org.apache.shiro.authc.UsernamePasswordToken;12 import org.apache.shiro.authz.AuthorizationInfo;13 import org.apache.shiro.authz.SimpleAuthorizationInfo;14 import org.apache.shiro.realm.AuthorizingRealm;15 import org.apache.shiro.subject.PrincipalCollection;16 17 public class MyRealm extends AuthorizingRealm {18 19 String getRoles() {20 System.out.println("查找权限!");21 return "sun";22 }23 24 /**25 * 角色、权限认证26 */27 @Override28 protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {29 SimpleAuthorizationInfo info=new SimpleAuthorizationInfo();30 //添加角色31 info.addRole(getRoles());32 //添加权限33 //info.addStringPermission("hello");34 return info;35 }36 37 /**38 * 身份认证39 */40 @Override41 protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {42 43 UsernamePasswordToken usernamePasswordToken = (UsernamePasswordToken) token;44 String password = new String(usernamePasswordToken.getPassword());45 if(usernamePasswordToken.getUsername().equals("admin") && password.equals("123456")) {46 Mapuser = new HashMap<>();47 user.put("username", "admin");48 user.put("password", "123456");49 return new SimpleAuthenticationInfo(user, user.get("password").toString(), this.getName());50 } else {51 throw new AccountException("帐号或密码不正确!");52 }53 }54 }
4.配置shiro
1 package com.xm.shiro.rbac; 2 3 import java.util.LinkedHashMap; 4 import java.util.Map; 5 6 import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor; 7 import org.apache.shiro.spring.web.ShiroFilterFactoryBean; 8 import org.apache.shiro.web.mgt.DefaultWebSecurityManager; 9 import org.springframework.context.annotation.Bean;10 import org.springframework.context.annotation.Configuration;11 import org.apache.shiro.mgt.SecurityManager;12 13 @Configuration14 public class ShiroConfig {15 16 @Bean17 public ShiroFilterFactoryBean shirFilter(SecurityManager securityManager) {18 ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();19 20 // 必须设置 SecurityManager21 shiroFilterFactoryBean.setSecurityManager(securityManager);22 23 // 如果不设置默认会自动寻找Web工程根目录下的"/login.jsp"页面24 shiroFilterFactoryBean.setLoginUrl("/login");25 26 // 拦截器.27 MapfilterChainDefinitionMap = new LinkedHashMap ();28 // 配置不会被拦截的链接 顺序判断29 filterChainDefinitionMap.put("/static/**", "anon");30 filterChainDefinitionMap.put("/doLogin/**", "anon");31 32 // :这是一个坑呢,一不小心代码就不好使了;33 // 34 filterChainDefinitionMap.put("/**", "authc");35 36 shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);37 System.out.println("Shiro拦截器工厂类注入成功");38 return shiroFilterFactoryBean;39 }40 41 /**42 * 注入MyRealm43 * @return44 */45 @Bean46 public SecurityManager securityManager() {47 DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();48 // 设置realm.49 securityManager.setRealm(myShiroRealm());50 return securityManager;51 }52 53 /**54 * 配置注解55 * @param securityManager56 * @return57 */58 @Bean59 public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager) {60 AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor61 = new AuthorizationAttributeSourceAdvisor();62 authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);63 return authorizationAttributeSourceAdvisor;64 }65 66 public MyRealm myShiroRealm() {67 return new MyRealm();68 }69 70 }
5.controller
注解:
常用的就这两种
(1)@RequiresPermissions("hello") =>是否具有hello权限
(2)@@RequiresRoles("sun")=>是否有sun角色
1 package com.xm.shiro.controller; 2 3 import org.apache.shiro.SecurityUtils; 4 import org.apache.shiro.authc.AuthenticationException; 5 import org.apache.shiro.authc.IncorrectCredentialsException; 6 import org.apache.shiro.authc.UsernamePasswordToken; 7 import org.apache.shiro.authz.annotation.RequiresPermissions; 8 import org.apache.shiro.subject.Subject; 9 import org.springframework.web.bind.annotation.GetMapping;10 import org.springframework.web.bind.annotation.PathVariable;11 import org.springframework.web.bind.annotation.RequestMapping;12 import org.springframework.web.bind.annotation.RestController;13 14 @RestController15 public class UserController {16 17 @RequiresPermissions("hello")18 @GetMapping("/hello")19 public String hello() {20 return "Hello Shiro!";21 }22 23 @GetMapping("/login")24 public String login() {25 return "权限管理";26 }27 28 @GetMapping("/doLogin/{username}/{password}")29 public String doLogin(@PathVariable("username") String username,@PathVariable("password") String password) {30 UsernamePasswordToken token = new UsernamePasswordToken(username, password);31 Subject currentUser = SecurityUtils.getSubject();32 try {33 currentUser.login(token);34 //此步将 调用realm的认证方法35 } catch(IncorrectCredentialsException e){36 //这最好把 所有的 异常类型都背会37 return "密码错误";38 } catch (AuthenticationException e) {39 return "登录失败";40 } 41 42 currentUser.hasRole("sun");43 currentUser.hasRole("sun");44 currentUser.hasRole("sun");45 currentUser.hasRole("sun");46 return token.getPrincipal()+":登录成功";47 }48 49 @GetMapping("/logout")50 public String logout() {51 Subject currentUser = SecurityUtils.getSubject();52 currentUser.logout();53 return "退出登录";54 }55 56 @GetMapping("/noUnauthorized")57 public String error() {58 return "无权限";59 }60 61 }