首先看下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. Ubuntu16.04部署python2和python3共存的Jupyter Notebook

    一.安装python和python-pip sudo apt-get install python python3 python-pip python3-pip sudo pip install -- ...

  2. 关于苹果真机 getFullYear()返回值为NAN的问题

    问题描述: 在html页面中获得后台传过来的一个时间并显示在页面上,我用getFullYear() ,getMonth(),getDate()分别获得了年月日在电脑上和三星手机上页面都能正确的显示时间 ...

  3. JS滚动加载

    var one = true;//设置一个全局变量 $(window).scroll(function () { var hight = document.body.scrollHeight - do ...

  4. 极化SAR图像基础知识(1)

    从今天开始学习极化SAR图像,记录于此. 极化散射矩阵S是用来表示单个像素散射特性的一种简便办法,它包含了目标的全部极化信息.

  5. Named function expressions demystified

    Introduction Surprisingly, a topic of named function expressions doesn't seem to be covered well eno ...

  6. CF #335 div1 A. Sorting Railway Cars

    题目链接:http://codeforces.com/contest/605/problem/A 大意是对一个排列进行排序,每一次操作可以将一个数字从原来位置抽出放到开头或结尾,问最少需要操作多少次可 ...

  7. JS模式--装饰者模式

    在Javascript中动态的给对象添加职责的方式称作装饰者模式. 下面我们通常遇到的例子: var a = function () { alert(1); };//改成: var a = funct ...

  8. 看我如何从一个APK到最终拿下域管理权限

    本文我将向大家介绍在企业网络中使用个人智能手机,会给我们企业网络造成怎样的潜在威胁?事实证明,想要欺骗一位企业内部的员工并让其安装恶意应用程序,其实并不困难.一旦成功,攻击者就可以突破企业内网的防护机 ...

  9. 进程间通信系列 之 命名管道FIFO及其应用实例

    进程间通信系列 之 概述与对比   http://blog.csdn.net/younger_china/article/details/15808685  进程间通信系列 之 共享内存及其实例   ...

  10. typedef和define的详细区别

    typedef是一种在计算机编程语言中用来声明自定义数据类型,配合各种原有数据类型来达到简化编程的目的的类型定义关键字. #define是预处理指令.下面让我们一起来看. typedef是C语言语句, ...