pom文件, springboot 2.x
<!--shiro--> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-spring</artifactId> <version>1.4.0</version> </dependency>
ShiroConfig.java
package com.example.shiro.config; import com.example.shiro.realm.UserRealm; import org.apache.shiro.mgt.SecurityManager; import org.apache.shiro.spring.LifecycleBeanPostProcessor; 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.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.DependsOn; import javax.servlet.Filter; import java.util.LinkedHashMap; import java.util.Map; /** * @Title: ShiroConfig * @ProjectName shiro * @date 2019/8/29:25 */ @Configuration public class ShiroConfig { @Value("${shiro.user.loginUrl}") public String loginUrl; @Value("${shiro.user.unauthorizedUrl}") private String unanthorizedUrl; /** * shiro 过滤器 * @param securityManager * @return */ @Bean public ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager) { ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean(); // Shiro的核心安全接口,这个属性是必须的 shiroFilterFactoryBean.setSecurityManager(securityManager); // 身份认证失败,则跳转到登录页面的配置 shiroFilterFactoryBean.setLoginUrl(loginUrl); // 权限认证失败,则跳转到指定页面 shiroFilterFactoryBean.setUnauthorizedUrl(unanthorizedUrl); // Shiro连接约束配置,即过滤链的定义,所有url都必须认证通过才可以访问; anon:所有url都都可以匿名访 LinkedHashMap<String, String> filterChainDefinitionMap = new LinkedHashMap<>(); // 对静态资源设置匿名访问 filterChainDefinitionMap.put("/favicon.ico**", "anon"); filterChainDefinitionMap.put("/sy.png**", "anon"); filterChainDefinitionMap.put("/css/**", "anon"); filterChainDefinitionMap.put("/docs/**", "anon"); filterChainDefinitionMap.put("/fonts/**", "anon"); filterChainDefinitionMap.put("/img/**", "anon"); filterChainDefinitionMap.put("/ajax/**", "anon"); filterChainDefinitionMap.put("/js/**", "anon"); filterChainDefinitionMap.put("/sy/**", "anon"); filterChainDefinitionMap.put("/druid/**", "anon"); filterChainDefinitionMap.put("/captcha/captchaImage**", "anon"); filterChainDefinitionMap.put("/logout", "logout"); // filterChainDefinitionMap.put("/login", "anon,captchaValidate"); filterChainDefinitionMap.put("/login", "anon"); filterChainDefinitionMap.put("/index", "anon"); // 定义filter Map<String, Filter> filters = new LinkedHashMap<String, Filter>(); // filters.put("onlineSession", onlineSessionFilter()); // filters.put("syncOnlineSession", syncOnlineSessionFilter()); // filters.put("captchaValidate", captchaValidateFilter()); // filters.put("kickout", kickoutSessionFilter()); // 注销成功,则跳转到指定页面 // filters.put("logout", logoutFilter()); shiroFilterFactoryBean.setFilters(filters); // 所有请求需要认证 filterChainDefinitionMap.put("/**", "user"); // user 登陆过 // filterChainDefinitionMap.put("/**", "user,kickout,onlineSession,syncOnlineSession"); shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap); return shiroFilterFactoryBean; } @Bean public SecurityManager securityManager(UserRealm userRealm) { DefaultWebSecurityManager defaultWebSecurityManager = new DefaultWebSecurityManager(); defaultWebSecurityManager.setRealm(userRealm); // 记住我 // securityManager.setRememberMeManager(rememberMeManager()); // 注入缓存管理器; // securityManager.setCacheManager(getEhCacheManager()); // session管理器 // securityManager.setSessionManager(sessionManager()); return defaultWebSecurityManager; } /** * 自定义Realm * EhCacheManager cacheManager */ @Bean public UserRealm userRealm() { UserRealm userRealm = new UserRealm(); // userRealm.setCacheManager(cacheManager); return userRealm; } /** * 开启Shiro注解通知器, 不然使用注解失效 */ @Bean public LifecycleBeanPostProcessor lifecycleBeanPostProcessor(){ return new LifecycleBeanPostProcessor(); } @Bean @DependsOn({"lifecycleBeanPostProcessor"}) public DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator(){ DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator = new DefaultAdvisorAutoProxyCreator(); advisorAutoProxyCreator.setProxyTargetClass(true); return advisorAutoProxyCreator; } @Bean public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager){ AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor(); authorizationAttributeSourceAdvisor.setSecurityManager(securityManager); return authorizationAttributeSourceAdvisor; } }
自定义Realm
package com.example.shiro.realm; import org.apache.shiro.SecurityUtils; 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 java.util.HashSet; import java.util.Set; /** * @Title: UserRealm * @ProjectName shiro * @date 2019/8/29:27 */ public class UserRealm extends AuthorizingRealm { /** * 授权 * @param principalCollection * @return */ @Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) { String username = (String) SecurityUtils.getSubject().getPrincipal(); SimpleAuthorizationInfo info = new SimpleAuthorizationInfo(); Set<String> stringSet = new HashSet<>(); stringSet.add("user:view:add"); stringSet.add("user:view:del"); Set<String> role = new HashSet<>(); role.add("admin"); info.setRoles(role); // set 角色 info.setStringPermissions(stringSet); // set 权限 return info; } /** * 每次登陆都会进入此方法,认证 * @param token * @return * @throws AuthenticationException */ @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException { System.out.println("-------身份认证方法--------"); UsernamePasswordToken upToken = (UsernamePasswordToken) token; String userName = upToken.getUsername(); String userPwd = upToken.getPassword() != null ? new String(upToken.getPassword()) : ""; //根据用户名从数据库获取密码进行对比 String password = "123qwe"; if (userName == null) { throw new AccountException("用户名不正确"); } else if (!userPwd.equals(password)) { throw new AccountException("密码不正确"); } return new SimpleAuthenticationInfo(userName, password, getName()); } }
设置
// 权限认证失败,则跳转到指定页面 shiroFilterFactoryBean.setUnauthorizedUrl(unanthorizedUrl);
设置跳转页面失败,报错情况增加异常处理即可.
package com.example.shiro.advice; import org.apache.shiro.authz.AuthorizationException; import org.apache.shiro.authz.UnauthorizedException; import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.ResponseBody; import javax.servlet.http.HttpServletRequest; /** * @Title: NoPermissionException * @ProjectName shiro * @date 2019/8/211:20 */ @ControllerAdvice public class NoPermissionException { @ResponseBody @ExceptionHandler(UnauthorizedException.class) public String handleShiroException(HttpServletRequest request,UnauthorizedException ex) { return "无权限"; } @ResponseBody @ExceptionHandler(AuthorizationException.class) public String AuthorizationException(HttpServletRequest request, AuthorizationException e) { return "权限认证失败"; } }
Controller
package com.example.shiro.controller; import org.apache.shiro.SecurityUtils; import org.apache.shiro.authc.UsernamePasswordToken; import org.apache.shiro.authz.annotation.RequiresPermissions; import org.apache.shiro.authz.annotation.RequiresRoles; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.ResponseBody; /** * @Title: ShiroController * @ProjectName shiro * @date 2019/8/210:20 */ @Controller public class ShiroController { @ResponseBody @GetMapping("login") public String login() { return "LOGIN"; } @ResponseBody @PostMapping("login") public String postLogin(String username,String password) { org.apache.shiro.subject.Subject subject = SecurityUtils.getSubject(); UsernamePasswordToken token = new UsernamePasswordToken(username,password); try { subject.login(token); } catch (Exception e) { return "登陆失败"; } return "登陆成功"; } @ResponseBody @RequiresPermissions("user:view:add") @GetMapping("add") public String add() { return "add"; } @ResponseBody @RequiresPermissions("user:view:del") @GetMapping("del") public String del() { return "del"; } @ResponseBody @GetMapping("userupdate") @RequiresRoles(value = "user") public String userupdate() { return "userupdate"; } @ResponseBody @GetMapping("viewselect") @RequiresPermissions("xxx:xxx:xxx") public String select() { return "select"; } @ResponseBody @RequiresRoles(value = "admin") @GetMapping("update") public String update() { return "update"; } @ResponseBody @GetMapping("unauth") public String unauth() { return "unauth 504 没有权限"; } @ResponseBody @GetMapping("loginout") public String loginOut() { SecurityUtils.getSubject().logout(); return "loginout"; } @GetMapping("index") public String index(){ return "index"; } }