首页 > 代码库 > springboot 集成shiro
springboot 集成shiro
首先看下shiro configuration 的配置,重要部分用红色标出了
package cn.xiaojf.today.shiro.configuration; import at.pollux.thymeleaf.shiro.dialect.ShiroDialect; import cn.xiaojf.today.sys.security.credentials.RetryLimitHashedCredentialsMatcher; import cn.xiaojf.today.sys.security.filter.MyLogoutFilter; import cn.xiaojf.today.sys.security.filter.RoleAuthorizationFilter; import cn.xiaojf.today.sys.security.realm.UsernameRealm; import cn.xiaojf.today.sys.service.SysResService; 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.boot.web.servlet.FilterRegistrationBean; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.filter.DelegatingFilterProxy; import javax.servlet.Filter; import java.util.LinkedHashMap; import java.util.Map; /** * shiro配置 * @author xiaojf 2017/2/10 11:30. */ @Configuration public class ShiroConfiguration { @Bean public FilterRegistrationBean filterRegistrationBean() { FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean(); filterRegistrationBean.setFilter(new DelegatingFilterProxy("shiroFilter")); filterRegistrationBean.addInitParameter("targetFilterLifecycle", "true"); filterRegistrationBean.setEnabled(true); filterRegistrationBean.addUrlPatterns("/*"); return filterRegistrationBean; } @Bean public RetryLimitHashedCredentialsMatcher credentialsMatcher() { RetryLimitHashedCredentialsMatcher credentialsMatcher = new RetryLimitHashedCredentialsMatcher(); credentialsMatcher.setHashAlgorithmName("sha"); credentialsMatcher.setHashIterations(2); credentialsMatcher.setStoredCredentialsHexEncoded(true); credentialsMatcher.setRetryCount(5); credentialsMatcher.setRetryTime(1800000); return credentialsMatcher; } @Bean public UsernameRealm usernameRealm(RetryLimitHashedCredentialsMatcher credentialsMatcher) { UsernameRealm usernameRealm = new UsernameRealm(); usernameRealm.setCredentialsMatcher(credentialsMatcher); usernameRealm.setCachingEnabled(true); return usernameRealm; } @Bean public LifecycleBeanPostProcessor lifecycleBeanPostProcessor() { return new LifecycleBeanPostProcessor(); } @Bean public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() { DefaultAdvisorAutoProxyCreator daap = new DefaultAdvisorAutoProxyCreator(); daap.setProxyTargetClass(true); return daap; } @Bean public DefaultWebSecurityManager securityManager(UsernameRealm usernameRealm) { DefaultWebSecurityManager dwsm = new DefaultWebSecurityManager(); dwsm.setRealm(usernameRealm); return dwsm; } @Bean public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(DefaultWebSecurityManager defaultWebSecurityManager) { AuthorizationAttributeSourceAdvisor aasa = new AuthorizationAttributeSourceAdvisor(); aasa.setSecurityManager(defaultWebSecurityManager); return aasa; } @Bean public MyLogoutFilter logoutFilter() { MyLogoutFilter myLogoutFilter = new MyLogoutFilter(); myLogoutFilter.setRedirectUrl("/login/index"); return myLogoutFilter; } @Bean(name = "shiroFilter") public ShiroFilterFactoryBean shiroFilterFactoryBean(DefaultWebSecurityManager securityManager, MyLogoutFilter logoutFilter, ApplicationContext context) { ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean(); shiroFilterFactoryBean.setSecurityManager(securityManager); shiroFilterFactoryBean.setLoginUrl("/login/index"); shiroFilterFactoryBean.setUnauthorizedUrl("/login/index"); Map<String, Filter> filters = new LinkedHashMap<>(); // filters.put("logout", logoutFilter); filters.put("role", new RoleAuthorizationFilter()); shiroFilterFactoryBean.getFilters().putAll(filters);//加载自定义拦截器 SysResService resService = context.getBean(SysResService.class);//只有通过这种方式才能获得resService,因为此处会优先于resService实例化 loadShiroFilterChain(shiroFilterFactoryBean,resService);//加载拦截规则 return shiroFilterFactoryBean; } private void loadShiroFilterChain(ShiroFilterFactoryBean shiroFilterFactoryBean,SysResService resService) { Map<String, String> filterChainDefinitionMap = new LinkedHashMap<>();
//默认拦截规则 filterChainDefinitionMap.put("/login/index", "anon"); filterChainDefinitionMap.put("/error/403", "anon"); filterChainDefinitionMap.put("/error/404", "anon"); filterChainDefinitionMap.put("/error/500", "anon"); filterChainDefinitionMap.put("/login/auth", "anon"); filterChainDefinitionMap.put("/logout", "logout"); filterChainDefinitionMap.put("/plugins/**", "anon"); filterChainDefinitionMap.put("/css/**", "anon"); filterChainDefinitionMap.put("/js/**", "anon"); filterChainDefinitionMap.put("/images/**", "anon"); //用户自定义拦截规则 filterChainDefinitionMap = resService.loadFilterChainDefinitions(filterChainDefinitionMap); //都不满足的时候,需要超级管理员权限才能访问 filterChainDefinitionMap.put("/**", "role[ROLE_SUPER]"); shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap); } @Bean public ShiroDialect shiroDialect() {//thymeleaf 集成shiro使用,如果没有可以删除 return new ShiroDialect(); } }
自定义realm,用于认证和授权
package cn.xiaojf.today.sys.security.realm; import cn.xiaojf.today.base.constant.DataStatus; import cn.xiaojf.today.base.constant.SystemConstant; import cn.xiaojf.today.sys.entity.SysUser; import cn.xiaojf.today.sys.service.SysUserService; 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 org.apache.shiro.util.ByteSource; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Lazy; import java.util.Set; /** * 根据用户名和密码校验登陆 * * @author xiaojf 2016-01-07 16:05:55 */ public class UsernameRealm extends AuthorizingRealm { /** * 系统用户service */ @Autowired @Lazy private SysUserService sysUserService; /** * 加载用户授权信息, 包括权限资源和角色\用户组资源 * * @author xiaojf 2016-01-07 16:05:55 */ @Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) { // 登陆名 String username = (String) principals.getPrimaryPrincipal(); SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo(); Set<String> roles = sysUserService.loadEnabledRolesByUsername(username); if (roles.contains(SystemConstant.ROLE_SUPER)) { authorizationInfo.addStringPermission("*"); }else { // 加载权限资源 authorizationInfo.setStringPermissions(sysUserService.loadEnabledPermissionsByUsername(username)); } // 加载角色/用户组 authorizationInfo.setRoles(roles); return authorizationInfo; } /** * 加载用户身份认证信息 * * @author xiaojf 2016-01-07 16:05:55 */ @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException { String username = (String) token.getPrincipal(); // 获取账号信息 SysUser sysUser = sysUserService.getByUsername(username); if (sysUser == null) { throw new UnknownAccountException(); // 没找到帐号 } if (sysUser.getStatus() == DataStatus.LOGIC_DELETE.getValue()) { throw new UnknownAccountException(); // 没找到帐号 } if (sysUser.getStatus() == DataStatus.DISABLE.getValue()) { throw new LockedAccountException(); // 帐号锁定 } SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(sysUser.getUsername(), sysUser.getPwd(), ByteSource.Util.bytes(sysUser.getSalt()), getName()); return authenticationInfo; } }
自定义登出过滤器
package cn.xiaojf.today.sys.security.filter; import org.apache.shiro.web.filter.authc.LogoutFilter; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; import java.util.Date; /** * 自定义退出过滤器 * @author xiaojf 294825811@qq.com * * 2015-3-20 */ public class MyLogoutFilter extends LogoutFilter { @Override protected boolean preHandle(ServletRequest request, ServletResponse response) throws Exception { return true; } }
自定义权限校验过滤器
package cn.xiaojf.today.sys.security.filter; import com.alibaba.fastjson.JSON; import cn.xiaojf.today.base.model.CommonResult; import org.apache.shiro.subject.Subject; import org.apache.shiro.util.CollectionUtils; import org.apache.shiro.util.StringUtils; import org.apache.shiro.web.filter.authz.AuthorizationFilter; import org.apache.shiro.web.util.WebUtils; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.PrintWriter; import java.util.Set; /** * 自定义认证器,区分ajax请求 * @author xiaojf 2017/2/10 11:30. */ public class RoleAuthorizationFilter extends AuthorizationFilter { public boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) throws IOException { Subject subject = getSubject(request, response); String[] rolesArray = (String[]) mappedValue; if (rolesArray == null || rolesArray.length == 0) { // no roles specified, so nothing to check - allow access. return true; } Set<String> roles = CollectionUtils.asSet(rolesArray); for (String role : roles) { if (subject.hasRole(role)) { return true; } } return false; } @Override protected boolean onAccessDenied(ServletRequest request, ServletResponse response, Object mappedValue) throws Exception { HttpServletRequest httpServletRequest = (HttpServletRequest) request; HttpServletResponse httpServletResponse = (HttpServletResponse) response; Subject subject = getSubject(request, response); if (subject.getPrincipal() == null) { if ("XMLHttpRequest".equalsIgnoreCase(httpServletRequest.getHeader("X-Requested-With"))) { httpServletResponse.setCharacterEncoding("UTF-8"); httpServletResponse.setHeader("Charset","UTF-8"); PrintWriter out = httpServletResponse.getWriter(); CommonResult result = new CommonResult(false); result.setCode("401"); result.setMsg("请重新登录"); out.write(JSON.toJSONString(result)); out.flush(); out.close(); } else { // saveRequestAndRedirectToLogin(request, response); String unauthorizedUrl = getUnauthorizedUrl(); WebUtils.issueRedirect(request, response, unauthorizedUrl); } } else { if ("XMLHttpRequest".equalsIgnoreCase(httpServletRequest.getHeader("X-Requested-With"))) { httpServletResponse.setCharacterEncoding("UTF-8"); httpServletResponse.setHeader("Charset","UTF-8"); PrintWriter out = httpServletResponse.getWriter(); CommonResult result = new CommonResult(false); result.setCode("403"); result.setMsg("没有足够的权限: "+((HttpServletRequest) request).getServletPath()); out.println(JSON.toJSONString(result)); out.flush(); out.close(); } else { String unauthorizedUrl = getUnauthorizedUrl(); if (StringUtils.hasText(unauthorizedUrl)) { WebUtils.issueRedirect(request, response, unauthorizedUrl); } else { WebUtils.toHttp(response).sendError(403); } } } return false; } }
springboot 集成shiro
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。