首先看下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. Extjs6(三)——用extjs6.0写一个简单页面

    本文基于ext-6.0.0 一.关于border布局 在用ext做项目的过程中,最常用到的一种布局就是border布局,现在要写的这个简单页面也是运用border布局来做.border布局将页面分为五 ...

  2. Linux 系统管理04--账号管理

    Linux系统管理04--账号管理 一.用户账号管理 1.用户账号概述 (1)用户账号的常见分类: 1>超级用户:root uid=0 gid=0 权限最大. 2>普通用户:uid> ...

  3. POJ 1741/1987 树的点分治

    树的点分治,主要思想是每次找子树的重心,计算经过根节点的情况数,再减去点对属于同一子树的情况. #include <iostream> #include <vector> #i ...

  4. NI Vision for LabVIEW 基础(一):NI Vision 简介

    NI Vision 控件模板 Vision控件模板位于LabVIEW控件模板的最顶层,由一下元素组成: IMAQ Image.ctl—该控件是一个类型定义,用于声明图象类型的数据.在VI的前面板中使用 ...

  5. 系统启动 之 Linux系统启动概述(2)

    博客:http://blog.csdn.net/younger_china/article/details/51615916 Linu系统启动是一个"冗长乏味"的过程,那么我们现就 ...

  6. 蓝桥杯-放麦子-java

    /* (程序头部注释开始) * 程序的版权和版本声明部分 * Copyright (c) 2016, 广州科技贸易职业学院信息工程系学生 * All rights reserved. * 文件名称: ...

  7. Scrollview中嵌套ListView(自定义组件解决)

    首先,ScrollView中只能放一个控件,一般都放LinearLayout,orientation属性值为vertical.在LinearLayout中放需要呈现的内容.ListView也在其中,L ...

  8. yum 安装redis 及简单命令(推荐测试环境,安装简单)

    第1章 redis 入门 1.1 yum 安装 安装repo源 cd /etc/yum.repos.d/ wget http://mirrors.aliyun.com/repo/epel-6.repo ...

  9. 转csdn-css4

    http://www.csdn.net/article/2015-03-06/2824127-css4

  10. 为Distinct准备的通用对比器

    使用Linq过滤重复对象的时候,我们使用Distinct. 但是Distinct对int long等值类型才有效果,对于对象我们需要自己写个对象. 以下利用泛型封装了两个类: CommonCompar ...