一、名词解释

网上一大堆

二、pom依赖

<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>1.2.2</version>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-ehcache</artifactId>
<version>1.2.2</version>
</dependency>

encache可选,主要用于鉴权时的缓存

三、shiroConfiguration

shiro的配置主要是shiroFilter和securityManager的设置

@Component
public class ShiroConfiguration {

@Bean
public EhCacheManager ehCacheManager()
{
EhCacheManager manager = new EhCacheManager();
manager.setCacheManagerConfigFile("classpath:ehcache-shiro.xml");
return manager;
} @Resource
private MyShiroRealm myShiroRealm;
@Bean
public SecurityManager securityManager()
{
DefaultWebSecurityManager defaultWebSecurityManager = new DefaultWebSecurityManager();
defaultWebSecurityManager.setRealm(myShiroRealm);
defaultWebSecurityManager.setCacheManager(ehCacheManager());
return defaultWebSecurityManager;
}
@Bean
public ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager)
{
ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
shiroFilterFactoryBean.setSecurityManager(securityManager);
Map<String,String> map = new LinkedHashMap<>();
Map<String,Filter> filterMap = new LinkedHashMap<>();
filterMap.put("authc",loginFilter());
filterMap.put("perms",myFilter());
shiroFilterFactoryBean.setFilters(filterMap); //map.put("/RPCAFA2A208FA648EA27C1EC30CADFC8B3D","anon");
//map.put("/**","authc");
map.put("/RPC52CA3404FDADAB18F91E8210DFCE1522","perms[admin:test]");
map.put("/RPC66EED9EBACF5FB42B9AD9C069495587F","perms[test]");
map.put("/**","authc");
//map.put("/**","myfilter");
shiroFilterFactoryBean.setFilterChainDefinitionMap(map);
return shiroFilterFactoryBean;
}
@Bean
public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager)
{
AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);
return authorizationAttributeSourceAdvisor;
}
/*@Bean
public MyShiroRealm myShiroRealm()
{
MyShiroRealm myShiroRealm = new MyShiroRealm();
//myShiroRealm.setCacheManager(manager);
return myShiroRealm;
}*/
@Bean
public LoginFilter loginFilter()
{
return new LoginFilter();
}
@Bean
public MyFilter myFilter()
{
return new MyFilter();
}
}

ehCahceManager是注册缓存管理器,MyShiroRealm是权限认证具体的实现,需要注册到securityManager中,shiroFilter中主要设置过滤器链。这里面我主要用到了两个过滤器,perms和authc。

perms是给访问URL设置访问权限的,比如map.put("/RPC52CA3404FDADAB18F91E8210DFCE1522","perms[admin:test]"),key是访问的URL,value是设置的权限,必须是perms[]的形式。我将需要访问的接口URL放到数据库中,在初始化配置的时候通过读取数据库将每一个需要鉴权的接口进行权限配置。authc要求必须登录认证。

由于我们是前后端分离,前端通过RPC接口访问后端服务,这块我就想当没有权限或者没有登录时,给前端返回不同的code,所以自己实现了两个filter,loginFilter替换原来的authc过滤器,myFilter替换原来的perms过滤器。

四、MyFilter和LoginFilter的实现

loginFilter继承AuthenticationFilter,myFilter继承PermissionsAuthorizationFilter

public class LoginFilter extends AuthenticationFilter {
@Override
protected boolean isAccessAllowed(ServletRequest servletRequest, ServletResponse servletResponse, Object o) {
HttpServletRequest request = (HttpServletRequest) servletRequest;
Subject subject = getSubject(servletRequest,servletResponse);
String path = request.getServletPath();
System.out.println("path = " + path);
if(path.equals("/RPCAFA2A208FA648EA27C1EC30CADFC8B3D"))
{
return true;
}
if(subject.getPrincipals() != null)
{
return true;
}
return false;
}
/**
* 会话超时或权限校验未通过的,统一返回401,由前端页面弹窗提示
*/
@Override
protected boolean onAccessDenied(ServletRequest request, ServletResponse response)
throws IOException { ShiroUtil.writeResponse((HttpServletResponse) response,new Result(AuthorizationStatus.NOT_LOGIN));
    return false; }
}

首先会执行isAccessAllowed方法,我将登录的几个接口在这里进行排除,直接返回true,就是登录的接口不需要进行登录认证。当返回false时执行onAccessDenied方法,这里我直接通过响应流返回给前端json数据。

public class ShiroUtil {

    /**
* 判断是否需要认证
* @param bean
* @return true 不需要 false 需要
*/
public static boolean isContains(NotAuthorizationBean bean)
{
List<String> paths = bean.getPaths();
String name = bean.getName();
for(String path : paths)
{
if(path.equalsIgnoreCase(name))
{
return true;
}
}
return false;
} /**
* 统一返回前端json数据
* @param response
* @param data
*/
public static void writeResponse(HttpServletResponse response, Object data)
{
try {
response.setContentType("application/json");
OutputStream outputStream = response.getOutputStream();
outputStream.write(JSON.toJSONString(data).getBytes("UTF-8"));
outputStream.flush();
outputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
public enum AuthorizationStatus {
NOT_LOGIN(401,"没有登录"),
NOT_AUTHORIZATION(403,"没有授权")
; private Integer code; private String msg; AuthorizationStatus(Integer code, String msg) {
this.code = code;
this.msg = msg;
} public Integer getCode() {
return code;
} public void setCode(Integer code) {
this.code = code;
} public String getMsg() {
return msg;
} public void setMsg(String msg) {
this.msg = msg;
}
}
public class Result {

    private Integer c;

    private String d;

    public Result(AuthorizationStatus status)
{
this.c = status.getCode();
this.d = status.getMsg();
} public Result(Integer c, String d) {
this.c = c;
this.d = d;
} public Integer getC() {
return c;
} public void setC(Integer c) {
this.c = c;
} public String getD() {
return d;
} public void setD(String d) {
this.d = d;
}
}

myFilter的实现类似,也是重写isAccessAllowed和onAccessDenied两个方法

public class MyFilter extends PermissionsAuthorizationFilter {
@Override
public boolean isAccessAllowed(ServletRequest servletRequest, ServletResponse servletResponse, Object o) throws IOException {
HttpServletRequest request = (HttpServletRequest) servletRequest; String path = request.getServletPath();
System.out.println("request path = " + path);
Subject subject = getSubject(servletRequest,servletResponse);
if(path.equals("/RPCAFA2A208FA648EA27C1EC30CADFC8B3D"))
{
return true;
}
/* String[] perms = (String[])((String[])o);
boolean isPermitted = true;
if(perms != null && perms.length > 0) {
if(perms.length == 1) {
if(!subject.isPermitted(perms[0])) {
isPermitted = false;
}
} else if(!subject.isPermittedAll(perms)) {
isPermitted = false;
}
}*/ return super.isAccessAllowed(servletRequest,servletResponse,o);
}
/**
* 会话超时或权限校验未通过的,统一返回401,由前端页面弹窗提示
*/
@Override
protected boolean onAccessDenied(ServletRequest request, ServletResponse response)
throws IOException {
System.out.println("no permission");
Subject subject = getSubject(request,response);
if(subject.getPrincipal() == null)
{
ShiroUtil.writeResponse((HttpServletResponse) response,new Result(AuthorizationStatus.NOT_LOGIN));
}else{
ShiroUtil.writeResponse((HttpServletResponse) response,new Result(AuthorizationStatus.NOT_AUTHORIZATION));
}
return false;
}
}

五、MyShiroRealm实现

realm是权限和登录管理的具体实现,需要继承AuthorizingRealm,实现doGetAuthorizationInfo权限认证和doGetAuthenticationInfo登录认证。

@Service
public class MyShiroRealm extends AuthorizingRealm {
@Resource
private UserInfoService userInfoService;
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
System.out.println("权限认证doGetAuthorizationInfo()");
String username = (String) super.getAvailablePrincipal(principalCollection);
System.out.println("username = " + username);
SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
//simpleAuthorizationInfo.addRole("admin");
simpleAuthorizationInfo.addStringPermission("admin:test");
return simpleAuthorizationInfo;
} @Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
System.out.println("登陆认证doGetAuthenticationInfo()");
UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken;
System.out.println("token = " + token.getUsername());
UserInfo userInfo = userInfoService.findByUsername(token.getUsername());
if(userInfo != null)
{
return new SimpleAuthenticationInfo(userInfo.getUsername(),userInfo.getPassword(),getName());
}
return null;
}
}

Springboot集成权限管理框架apache shiro的更多相关文章

  1. 权限框架Apache Shiro 和 Spring Security

    Shiro 首先Shiro较之 Spring Security,Shiro在保持强大功能的同时,还在简单性和灵活性方面拥有巨大优势.Shiro是一个强大而灵活的开源安全框架,能够非常清晰的处理认证.授 ...

  2. Apache Shiro 开源权限框架

    在 Web 项目中应用 Apache Shiro 开源权限框架 Apache Shiro 是功能强大并且容易集成的开源权限框架,它能够完成认证.授权.加密.会话管理等功能.认证和授权为权限控制的核心, ...

  3. 让Apache Shiro保护你的应用

    在尝试保护你的应用时,你是否有过挫败感?是否觉得现有的Java安全解决方案难以使用,只会让你更糊涂?本文介绍的Apache Shiro,是一个不同寻常的Java安全框架,为保护应用提供了简单而强大的方 ...

  4. Apache Shiro 使用手册(三)Shiro 授权

    授权即访问控制,它将判断用户在应用程序中对资源是否拥有相应的访问权限. 如,判断一个用户有查看页面的权限,编辑数据的权限,拥有某一按钮的权限,以及是否拥有打印的权限等等. 一.授权的三要素 授权有着三 ...

  5. Apache Shiro 手册

    (一)Shiro架构介绍 一.什么是Shiro Apache Shiro是一个强大易用的Java安全框架,提供了认证.授权.加密和会话管理等功能: 认证 - 用户身份识别,常被称为用户"登录 ...

  6. Apache Shiro 使用手册---转载

    原文地址:http://www.360doc.com/content/12/0104/13/834950_177177202.shtml (一)Shiro架构介绍 一.什么是Shiro Apache ...

  7. Apache Shiro 使用手册

    http://kdboy.iteye.com/blog/1154644 (一)Shiro架构介绍 一.什么是Shiro  Apache Shiro是一个强大易用的Java安全框架,提供了认证.授权.加 ...

  8. Apache shiro集群实现 (四)shiro授权(Authentication)--访问控制

    Apache shiro集群实现 (一) shiro入门介绍 Apache shiro集群实现 (二) shiro 的INI配置 Apache shiro集群实现 (三)shiro身份认证(Shiro ...

  9. Apache Shiro 使用手册(三)Shiro 授权(转发:http://kdboy.iteye.com/blog/1155450)

    授权即访问控制,它将判断用户在应用程序中对资源是否拥有相应的访问权限. 如,判断一个用户有查看页面的权限,编辑数据的权限,拥有某一按钮的权限,以及是否拥有打印的权限等等. 一.授权的三要素 授权有着三 ...

随机推荐

  1. [CF877F]Ann and Books

    题目大意: 有$n(n\le10^5)$个数$w_{1\sim n}(|w_i|\le10^9)$,并给定一个数$k(|k|\le10^9)$.$q(q\le10^5)$次询问,每次询问区间$[l,r ...

  2. java web定时任务---Timer

    写在前面: 在最近的项目中需要每天定时对数据库表进行查询,并完成相关数据的更新操作.首先让我想到的是Timer类,记得在一开始维护那个老系统的时候,开了个接口,也涉及到了定时的操作.下面就记录下大概的 ...

  3. SVN 文件删除及恢复

    SVN 文件删除及恢复 在TortoiseSVN管理的项目中删除文件的方法:   1. 在客户端按delete删除(OS中删除,不通过SVN)           ● 未提交之前一旦Update则被删 ...

  4. select * from sys.sysprocesses

    MSDN:包含正在 SQL Server 实例上运行的进程的相关信息.这些进程可以是客户端进程或系统进程. 视图中主要的字段: 1. Spid:Sql Servr 会话ID 2. Kpid:Windo ...

  5. Vue 单页应用:记事本

    若文章中存在内容无法加载的情况,请移步作者其他博客. 简书 CSDN 最近在看 Vue 的时候,别人给我安利了一个国外的小案例,通过 Vue 和 Vuex 来实现一个记事本. 仔细剖析下,发现“麻雀虽 ...

  6. Jenkins持续集成实战总结

    原文:https://my.oschina.net/CandyDesire/blog/341331#comment-list 持续集成 什么是持续集成 随着软件开发复杂度的不断提高,团队开发成员间如何 ...

  7. coco2dx jni 调用 java 相机返回 图片数据

    新建 一个项目 名字:testJin  包名:com.TanSon.org  python命令:python create_project.py -project testJin -package c ...

  8. LNMP第二部分nginx、php配置

    内容概要:一. nginx.confvim /usr/local/nginx/conf/nginx.conf //清空原来的配置,加入如下内容:user nobody nobody;worker_pr ...

  9. C++之string学习

    #define _CRT_SECURE_NO_WARNINGS #include <iostream> #include <list> #include <string& ...

  10. [GitHub开源]基于HTML5实现的轻量级Google Earth三维地图引擎,带你畅游世界 【转】

    http://blog.csdn.net/iispring/article/details/52679185 WebGlobe HTML5基于原生WebGL实现的轻量级Google Earth三维地图 ...