1、依赖:

        <dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-core</artifactId>
<version>1.4.0</version>
</dependency> <dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>1.4.0</version>
</dependency> <dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-web</artifactId>
<version>1.4.0</version>
</dependency> <dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.8.9</version>
</dependency>

2、自定义Realm:

package com.example.demo_mg.realm;

import org.apache.commons.collections.map.HashedMap;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.crypto.hash.Md5Hash;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource; import java.util.*; public class TestRealm extends AuthorizingRealm {
//模拟users、user_roles、roles_permissions三张表的查询,实际应用需要查询数据库或缓存
Map<String, String> users = new HashMap<>();
Map<String, Set<String>> user_roles = new HashedMap();
Map<String, Set<String>> roles_permissions = new HashedMap();
// String salt = UUID.randomUUID().toString().replaceAll("-",""); {
//不加盐(与认证对应)
users.put("wzs", new Md5Hash("123456",null, 2).toString());
//加盐
// users.put("wzs", new Md5Hash("123456",salt, 2).toString());
user_roles.put("wzs", new HashSet<>(Arrays.asList("admin", "test")));
roles_permissions.put("admin", new HashSet<>(Arrays.asList("user:delete", "user:update")));
super.setName("TestRealm"); //设置Realm名称,可选
} @Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
//从认证信息获取用户名
String username = (String)principalCollection.getPrimaryPrincipal();
//从数据库或缓存中获取角色、权限数据
Set<String> roles = user_roles.get(username);
Set<String> permissions = new HashSet<>();
for (String role : roles) {
Set<String> set;
if((set = roles_permissions.get(role)) != null) {
permissions.addAll(set);
}
}
SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
simpleAuthorizationInfo.setRoles(roles);
simpleAuthorizationInfo.setStringPermissions(permissions);
return simpleAuthorizationInfo;
} @Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
//从主题传过来的认证信息中,获得用户名
String username = (String)authenticationToken.getPrincipal();
//通过用户名从数据库中获取凭证
String password = users.get(username);
if(password != null) {
//不加盐
// return new SimpleAuthenticationInfo(username, password, super.getName());
//加盐
SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(username, password, super.getName());
// simpleAuthenticationInfo.setCredentialsSalt(ByteSource.Util.bytes(salt));
return simpleAuthenticationInfo;
}
return null;
}
}

3、配置:

package com.example.demo_mg.config;

import com.example.demo_mg.realm.TestRealm;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.mgt.SecurityManager;
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.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import java.util.LinkedHashMap; @Configuration
public class ShiroConfiguration {
@Bean
public HashedCredentialsMatcher getCredentialsMatcher() {
HashedCredentialsMatcher credentialsMatcher = new HashedCredentialsMatcher();
credentialsMatcher.setHashAlgorithmName("md5");
credentialsMatcher.setHashIterations(2);
return credentialsMatcher;
} @Bean
public TestRealm getRealm(HashedCredentialsMatcher credentialsMatcher) {
TestRealm testRealm = new TestRealm();
testRealm.setCredentialsMatcher(credentialsMatcher);
return testRealm;
} @Bean
public DefaultWebSecurityManager getDefaultWebSecurityManager(TestRealm testRealm) {
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
securityManager.setRealm(testRealm);
return securityManager;
} @Bean
public ShiroFilterFactoryBean getShiroFilter(SecurityManager securityManager) {
ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
shiroFilterFactoryBean.setSecurityManager(securityManager);
shiroFilterFactoryBean.setLoginUrl("login.html");
shiroFilterFactoryBean.setUnauthorizedUrl("403.html");
LinkedHashMap<String, String> filterChainDefinitionMap = new LinkedHashMap<>();
filterChainDefinitionMap.put("/login.html", "anon");
filterChainDefinitionMap.put("/login", "anon");
filterChainDefinitionMap.put("/*", "authc");
shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
return shiroFilterFactoryBean;
} /**
* 注解式授权2个bean
* @return
*/
//Shiro生命周期处理器
@Bean
public LifecycleBeanPostProcessor getLifecycleBeanPostProcessor() {
return new LifecycleBeanPostProcessor();
} @Bean
public AuthorizationAttributeSourceAdvisor getAuthorizationAttributeSourceAdvisor(SecurityManager securityManager) {
AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);
return authorizationAttributeSourceAdvisor;
}
}

4、实体:

package com.example.demo_mg.entity;

public class User {
private String username;
private String password; public String getPassword() {
return password;
} public void setPassword(String password) {
this.password = password;
} public String getUsername() {
return username;
} public void setUsername(String username) {
this.username = username;
}
}

5、控制器:

package com.example.demo_mg.controller;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.apache.shiro.authz.annotation.RequiresRoles;
import org.apache.shiro.subject.Subject;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod; @Controller
public class LoginContrller {
@RequestMapping(value = "/login",method = RequestMethod.GET)
public String loginUser(String username, String password) {
UsernamePasswordToken usernamePasswordToken = new UsernamePasswordToken(username, password);
Subject subject = SecurityUtils.getSubject();
try {
subject.login(usernamePasswordToken); //完成登录
//更新用户登录时间,也可以在ShiroRealm里面做
return "index";
} catch(Exception e) {
return "login";//返回登录页面
}
} @RequestMapping("/logout")
public String logout() {
Subject subject = SecurityUtils.getSubject();
subject.logout();
return "login";
} @RequestMapping("/test")
public void test() {
System.out.println("test");
} @RequiresRoles("admin")
@RequestMapping("/role")
public void role() {
System.out.println("role");
} @RequiresPermissions("user:delete1")
@RequestMapping("/permission")
public void permission() {
System.out.println("permission");
}
}

6、自定义过滤器,授权继承AuthorizationFilter,认证继承AuthenticatinFilter,可以阅读其源码。

Shiro提供的认证过滤器包括anon,authBasic,authc,user,logout,授权过滤器包括perms,roles,ssl,port,举例perms["user:delete","user:update"],roles["admin","user"],方括号内的角色或权限需要同时满足,否则跳到unauthorizadUrl,ssl是https过滤器。

自定义过滤器例子,角色满足一个即可:

package com.example.demo_mg.filter;

import org.apache.shiro.subject.Subject;
import org.apache.shiro.web.filter.authz.AuthorizationFilter; import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse; public class RoleOrFilter extends AuthorizationFilter {
@Override
protected boolean isAccessAllowed(ServletRequest servletRequest, ServletResponse servletResponse, Object o) throws Exception {
Subject subject = getSubject(servletRequest, servletResponse);
String[] roles = (String[])o;
if(roles == null || roles.length == 0) {
return true;
}
for (String role : roles) {
if(subject.hasRole(role)) {
return true;
}
}
return false;
}
}

拿到subject,o是配置的过滤器方括号里面的数组,return true;表示通过过滤器。

配置类修改使自定义过滤器生效:

    @Bean
public ShiroFilterFactoryBean getShiroFilter(SecurityManager securityManager) {
ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
shiroFilterFactoryBean.setSecurityManager(securityManager);
shiroFilterFactoryBean.setLoginUrl("login.html");
shiroFilterFactoryBean.setUnauthorizedUrl("403.html");
LinkedHashMap<String, String> filterChainDefinitionMap = new LinkedHashMap<>();
filterChainDefinitionMap.put("/login.html", "anon");
filterChainDefinitionMap.put("/login", "anon");
filterChainDefinitionMap.put("/filter", "roleOr[admin,user]");
filterChainDefinitionMap.put("/*", "authc");
shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
//自定义拦截器
LinkedHashMap<String, Filter> filters = new LinkedHashMap<>();
filters.put("roleOr", getRoleOrFilter());
shiroFilterFactoryBean.setFilters(filters);
return shiroFilterFactoryBean;
} @Bean
public RoleOrFilter getRoleOrFilter() {
RoleOrFilter roleOrFilter = new RoleOrFilter();
return roleOrFilter;
}

测试:

    @RequestMapping("/filter")
public void filter() {
System.out.println("filter");
}

Apache Shiro 集成Spring(二)的更多相关文章

  1. 【权限管理】Apache Shiro和Spring Security的对比

    一.Shiro简介 Apache Shiro是Java的一个安全框架.目前,使用Apache Shiro的人越来越多,因为它相当简单,对比Spring Security,可能没有Spring Secu ...

  2. apache shiro整合spring(一)

    apache shiro整合spring 将shiro配置文件整合到spring体系中 方式一:直接在spring的配置文件中import shiro的配置文件 方式二:直接在web.xml中配置sh ...

  3. Apache Shiro和Spring Security的详细对比

    参考资料: 1)Apache Shiro Apache Shiro:http://shiro.apache.org/ 在Web项目中应用 Apache Shiro:http://www.ibm.com ...

  4. Shiro集成Spring

    本篇博客主要讲述的是两者的集成.不涉及到各自的详细细节和功能. 因为官方给出的文档不够具体,对新手而言通过官方文档还不可以非常快的搭建出SpringShiro的webproject.本博客将通过实际的 ...

  5. shiro 集成spring 配置 学习记录(一)

    首先当然是项目中需要增加shiro的架包依赖: <!-- shiro --> <dependency> <groupId>org.apache.shiro</ ...

  6. shiro集成spring&工作流程&DelegatingFilterProxy

    1.集成Spring 参考文献: 新建web工程: ehcache-core来自Hibernate wen.xml <?xml version="1.0" encoding= ...

  7. Apache Shiro 集成-Cas

    http://blog.csdn.net/peterwanghao/article/details/8825008 Shiro集成CAS是在1.2版本里新增的功能. Shiro-cas模块将应用作为C ...

  8. shiro 集成spring 使用 redis作为缓存 学习记录(六)

    1.在applicationContext-redis.xml配置文件中增加如下: 申明一个cacheManager对象 用来注入到  shiro的   securityManager 属性  cac ...

  9. shiro学习(四、shiro集成spring+springmvc)

    依赖:spring-context,spring-MVC,shiro-core,shiro-spring,shiro-web 实话实说:web.xml,spring,springmvc配置文件好难 大 ...

随机推荐

  1. 连接tomcat时,输入telnet localhost 8080后无法再次输入

    初次接触服务器时,一般会在本地建立一个微型服务器,今天在使用Apache的tomcat时,为了在命令行下访问服务器中webapps下的自定义资源:首先打开命令行窗口,然后输入telnet localh ...

  2. C++ STL常见数据结构(容器)分类

    vector:(连续的空间存储,可以使用[]操作符)快速的访问随机的元素,快速的在末尾插入元素,但是在序列中间的插入,删除元素要慢,而且如果一开始分配的空间不够的话,可能重新分配更大空间,拷贝的性能开 ...

  3. opencv视频流的读取和处理

    Opencv提供一个简单易用的框架以提取视频文件和USB摄像头中的图像帧,如果只是想读取某个视频,你只需要创建一个VideoCapture实例,然后在循环中提取每一帧.下面是一个简单的代码 #incl ...

  4. JS-03 牛客网练习

    1.很多人都使用过牛客网这个在线编程网站,下面是自己做的该项所有练习,已通过网站和老师检查无误,分享给大家. 2.先说一下题目的位置:牛客网https://www.nowcoder.com/activ ...

  5. rpmbuild - 构建 RPM 打包

    SYNOPSIS 构建打包: rpmbuild {-ba|-bb|-bp|-bc|-bi|-bl|-bs} [rpmbuild-options] SPECFILE ... rpmbuild {-ta| ...

  6. django允许外部访问 项目后台不挂断运行

    1关闭防火墙 1 service iptables stop 2设置django 1 2 3 4 5 6 7 8 9 10 11 开开启django时,使用0.0.0.0:xxxx,作为ip和端口例如 ...

  7. ArrayList、LinkedList、Vector区别

    ArrayList.LinkedList.Vector均为可伸缩数组,即可以动态改变长度的数组. 比较ArrayList和Vector: 1. 共同点: ArrayList和Vector都是基于Obj ...

  8. MySQL系列之三查询优化

    通常来说,查询的生命周期大致可以按照顺序来看从客户端到服务端,然后在服务器上进行解析,生产执行计划, 执行,并返回结果给客户端.其中的执行阶段可以认为是整个生命周期中最重要的阶段,其中包括了大量为了检 ...

  9. 第04章 AOP概述

    第04章 AOP概述 1.AOP概述 ●AOP(Aspect-Oriented Programming,面向切面编程):是一种新的方法论,是对传统 OOP(Object-Oriented Progra ...

  10. cocos2D-X Doc

    { //https://docs.cocos2d-x.org/api-ref/index.html //https://docs.cocos.com/cocos2d-x/manual/zh/sprit ...