Apache Shiro 集成Spring(二)
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(二)的更多相关文章
- 【权限管理】Apache Shiro和Spring Security的对比
一.Shiro简介 Apache Shiro是Java的一个安全框架.目前,使用Apache Shiro的人越来越多,因为它相当简单,对比Spring Security,可能没有Spring Secu ...
- apache shiro整合spring(一)
apache shiro整合spring 将shiro配置文件整合到spring体系中 方式一:直接在spring的配置文件中import shiro的配置文件 方式二:直接在web.xml中配置sh ...
- Apache Shiro和Spring Security的详细对比
参考资料: 1)Apache Shiro Apache Shiro:http://shiro.apache.org/ 在Web项目中应用 Apache Shiro:http://www.ibm.com ...
- Shiro集成Spring
本篇博客主要讲述的是两者的集成.不涉及到各自的详细细节和功能. 因为官方给出的文档不够具体,对新手而言通过官方文档还不可以非常快的搭建出SpringShiro的webproject.本博客将通过实际的 ...
- shiro 集成spring 配置 学习记录(一)
首先当然是项目中需要增加shiro的架包依赖: <!-- shiro --> <dependency> <groupId>org.apache.shiro</ ...
- shiro集成spring&工作流程&DelegatingFilterProxy
1.集成Spring 参考文献: 新建web工程: ehcache-core来自Hibernate wen.xml <?xml version="1.0" encoding= ...
- Apache Shiro 集成-Cas
http://blog.csdn.net/peterwanghao/article/details/8825008 Shiro集成CAS是在1.2版本里新增的功能. Shiro-cas模块将应用作为C ...
- shiro 集成spring 使用 redis作为缓存 学习记录(六)
1.在applicationContext-redis.xml配置文件中增加如下: 申明一个cacheManager对象 用来注入到 shiro的 securityManager 属性 cac ...
- shiro学习(四、shiro集成spring+springmvc)
依赖:spring-context,spring-MVC,shiro-core,shiro-spring,shiro-web 实话实说:web.xml,spring,springmvc配置文件好难 大 ...
随机推荐
- C. DZY Loves Sequences
C. DZY Loves Sequences time limit per test 1 second memory limit per test 256 megabytes input standa ...
- day50 初识JavaScript
一.背景介绍 (一)web开发的三种样式: 结构:HTML:从语义的角度,描述页面结构 样式:CSS:从审美的角度,描述样式(美化页面) 行为(动态)JavaScript:从交互的角度,描述行为(用于 ...
- Linux查看关闭进程
ps:进程的静态列表(Process status) - PID:进程号,每个进程独一无二的标识符(关闭进程需要使用) - TTY:终端所属,表明进程产生于哪一个终端,对于多用户使用的Linux服务器 ...
- 实现多线程的三种方法:Thread、Runnable和Callable
继承Thread类,重写run()方法 步骤: (1) 定义类继承Thread类 (2) 复写Thread类中的run方法. (3) 调用线程的start方法 (start方法有两种含义:1. 启动多 ...
- Oracle数据库同义词
一.定义 同义词顾名思义,是数据库方案对象的一个别名.这里的数据库方案对象指表.视图.序列.存储过程.包等. 二.同义词的好处 1.不占内存空间,节省大量的数据库空间 2.简化了数据库对象的访问 3. ...
- PHP: 双层 for循环的执行过程
先看代码 <?php for ($i = 0; $i<3; $i++) { for ($x = 0; $x<3; $x++) { // code... } } ?> 看下它的执 ...
- github托管代码
安装git客户端 github是服务端,要想在自己电脑上使用git我们还需要一个git客户端, windows用户请下载 http://msysgit.github.com/ mac用户请下载 htt ...
- Spring-quartz定时系统多任务配置
<!-- 启动触发器的配置开始 --> <bean name="startQuertz" lazy-init="false" autowire ...
- angular 组件通信
单页面应用组件通信有以下几种,这篇文章主要讲 Angular 通信 父组件 => 子组件 子组件 => 父组件 组件A = > 组件B 父组件 => 子组件 子组件 => ...
- Java 实现文件复制的不同方法
用不同的方法实现文件的复制 1. 通道 Channel,它是一个对象,可以通过它读取和写入数据.拿NIO与原来的I/O比较,通道就像是流.是对接操作系统底层和缓冲区的桥梁. 2. 性能比较 内存映射最 ...