首先看下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的更多相关文章

  1. SpringBoot集成Shiro并用MongoDB做Session存储

    之前项目鉴权一直使用的Shiro,那是在Spring MVC里面使用的比较多,而且都是用XML来配置,用Shiro来做权限控制相对比较简单而且成熟,而且我一直都把Shiro的session放在mong ...

  2. springboot集成shiro实现权限认证

    github:https://github.com/peterowang/shiro 基于上一篇:springboot集成shiro实现身份认证 1.加入UserController package ...

  3. SpringBoot集成Shiro 实现动态加载权限

    一.前言 本文小编将基于 SpringBoot 集成 Shiro 实现动态uri权限,由前端vue在页面配置uri,Java后端动态刷新权限,不用重启项目,以及在页面分配给用户 角色 . 按钮 .ur ...

  4. SpringBoot学习笔记(五):SpringBoot集成lombok工具、SpringBoot集成Shiro安全框架

    SpringBoot集成lombok工具 什么是lombok? 自动生成setget方法,构造函数,打印日志 官网:http://projectlombok.org/features/index. 平 ...

  5. SpringBoot集成Shiro安全框架

    跟着我的步骤:先运行起来再说 Spring集成Shiro的GitHub:https://github.com/yueshutong/shiro-imooc 一:导包 <!-- Shiro安全框架 ...

  6. springboot集成shiro 实现权限控制(转)

    shiro apache shiro 是一个轻量级的身份验证与授权框架,与spring security 相比较,简单易用,灵活性高,springboot本身是提供了对security的支持,毕竟是自 ...

  7. 【Shiro】SpringBoot集成Shiro

    项目版本: springboot2.x shiro:1.3.2 Maven配置: <dependency> <groupId>org.apache.shiro</grou ...

  8. SpringBoot集成Shiro实现权限控制

    Shiro简介 Apache Shiro是一个功能强大且易于使用的Java安全框架,用于执行身份验证,授权,加密和会话管理.使用Shiro易于理解的API,您可以快速轻松地保护任何应用程序-从最小的移 ...

  9. springboot集成shiro——使用RequiresPermissions注解无效

    在Springboot环境中继承Shiro时,使用注解@RequiresPermissions时无效 @RequestMapping("add") @RequiresPermiss ...

随机推荐

  1. STM32固件库文件分析

    STM32固件库文件分析 1.汇编编写的启动文件 startup/stm32f10x.hd.s:设置堆栈指针,设置pc指针,初始化中断向量,配置系统时钟,对用c库函数_main最后去c语言世界里. 2 ...

  2. java复习(2)---java基础杂记

    java命名规范: 参考:http://www.cnblogs.com/maowang1991/archive/2013/06/29/3162366.html 1.项目名小写 2.包名小写 3.类名每 ...

  3. Linux-粘滞位的使用

    粘滞位(Stickybit),又称粘着位,是Unix文件系统权限的一个旗标.最常见的用法在目录上设置粘滞位, 也只能针对⽬录设置,对于⽂件⽆效.则设置了粘滞位后,只有目录内文件的所有者或者root才可 ...

  4. 利刃 MVVMLight 7:命令深入

    上面一篇我们大致了解了命令的基本使用方法和基础原理,但是实际在运用命令的时候会复杂的多,并且有各种各样的情况. 一.命令带参数的情况: 如果视图控件所绑定的命令想要传输参数,需要配置 CommandP ...

  5. DFB系列 之 SetCooperativeLevel协作级别

    1. 函数原型解析 函数声明 function SetCooperativeLevel(hWnd: HWND; dwFlags: DWORD): HResult; stdcall; 设置指定的IDir ...

  6. 详解Java反射机制

    反射是程序在运行状态下,动态的获取某个类的内部信息的一种操作.例如:类名,包名,所有属性的集合,所有方法的集合,构造方法的集合等.该操作发生在程序的运行时状态,所以编译器管不着有关反射的一些代码,通常 ...

  7. python之基础中的基础(一)

    python是一个效率极高的语言,现在市面上的机器学习大部分是由python和R语言完成,所以在不久之前小仙心中便种下了学习python的想法.下面是这一个月多月以来学习的总结,都是基础中基础了. 1 ...

  8. glassfish PWC6351: In TLD scanning 系统找不到指定的文件问题解决

    [2017-04-25T21:26:09.391+0800] [glassfish 4.1] [WARNING] [] [org.apache.jasper.runtime.TldScanner] [ ...

  9. (转)详解JS位置、宽高属性之一:offset系列

    很多初学者对于JavaScript中的offset.scroll.client一直弄不明白,虽然网上到处都可以看一张图(图1),但这张图太多太杂,并且由于浏览器差异性,图示也不完全正确. 图一 不知道 ...

  10. Azure Event Bus 技术研究系列1-Event Hub入门篇

    前两个系列研究了Azure IoT Hub和Azure Messaging.最近准备继续研究Azure Event Bus,即Azure的事件中心.首先, Azure Event Hub的官方介绍: ...