springboot集成shiro 实现权限控制(转)
shiro
apache shiro 是一个轻量级的身份验证与授权框架,与spring security 相比较,简单易用,灵活性高,springboot本身是提供了对security的支持,毕竟是自家的东西。springboot暂时没有集成shiro,这得自己配。
shiro 内置过滤器
请看博文:
http://blog.csdn.net/hxpjava1/article/details/7035724
本文实现:
本文实现从数据库读取用户信息,获取当前用户的权限或角色,通过配置文件过滤用户的角色或权限。拥有相应的角色或者相应的权限的用户可以访问相应的url。
数据库设计
1. 添加依赖
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>1.2.5</version>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-ehcache</artifactId>
<version>1.2.5</version>
</dependency>
<dependency>
<groupId>com.github.theborakompanioni</groupId>
<artifactId>thymeleaf-extras-shiro</artifactId>
<version>1.2.1</version>
</dependency>
2. 添加shiro 配置
package com.us.shiro;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
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.filter.authc.LogoutFilter;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.DependsOn;
import javax.servlet.Filter;
import java.util.LinkedHashMap;
import java.util.Map;
/**
* shiro配置类
* Created by cdyoue on 2016/10/21.
*/
@Configuration
public class ShiroConfiguration {
/**
* LifecycleBeanPostProcessor,这是个DestructionAwareBeanPostProcessor的子类,
* 负责org.apache.shiro.util.Initializable类型bean的生命周期的,初始化和销毁。
* 主要是AuthorizingRealm类的子类,以及EhCacheManager类。
*/
@Bean(name = "lifecycleBeanPostProcessor")
public LifecycleBeanPostProcessor lifecycleBeanPostProcessor() {
return new LifecycleBeanPostProcessor();
}
/**
* HashedCredentialsMatcher,这个类是为了对密码进行编码的,
* 防止密码在数据库里明码保存,当然在登陆认证的时候,
* 这个类也负责对form里输入的密码进行编码。
*/
@Bean(name = "hashedCredentialsMatcher")
public HashedCredentialsMatcher hashedCredentialsMatcher() {
HashedCredentialsMatcher credentialsMatcher = new HashedCredentialsMatcher();
credentialsMatcher.setHashAlgorithmName("MD5");
credentialsMatcher.setHashIterations(2);
credentialsMatcher.setStoredCredentialsHexEncoded(true);
return credentialsMatcher;
}
/**ShiroRealm,这是个自定义的认证类,继承自AuthorizingRealm,
* 负责用户的认证和权限的处理,可以参考JdbcRealm的实现。
*/
@Bean(name = "shiroRealm")
@DependsOn("lifecycleBeanPostProcessor")
public ShiroRealm shiroRealm() {
ShiroRealm realm = new ShiroRealm();
// realm.setCredentialsMatcher(hashedCredentialsMatcher());
return realm;
}
// /**
// * EhCacheManager,缓存管理,用户登陆成功后,把用户信息和权限信息缓存起来,
// * 然后每次用户请求时,放入用户的session中,如果不设置这个bean,每个请求都会查询一次数据库。
// */
// @Bean(name = "ehCacheManager")
// @DependsOn("lifecycleBeanPostProcessor")
// public EhCacheManager ehCacheManager() {
// return new EhCacheManager();
// }
/**
* SecurityManager,权限管理,这个类组合了登陆,登出,权限,session的处理,是个比较重要的类。
// */
@Bean(name = "securityManager")
public DefaultWebSecurityManager securityManager() {
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
securityManager.setRealm(shiroRealm());
// securityManager.setCacheManager(ehCacheManager());
return securityManager;
}
/**
* ShiroFilterFactoryBean,是个factorybean,为了生成ShiroFilter。
* 它主要保持了三项数据,securityManager,filters,filterChainDefinitionManager。
*/
@Bean(name = "shiroFilter")
public ShiroFilterFactoryBean shiroFilterFactoryBean() {
ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
shiroFilterFactoryBean.setSecurityManager(securityManager());
Map<String, Filter> filters = new LinkedHashMap<>();
LogoutFilter logoutFilter = new LogoutFilter();
logoutFilter.setRedirectUrl("/login");
// filters.put("logout",null);
shiroFilterFactoryBean.setFilters(filters);
Map<String, String> filterChainDefinitionManager = new LinkedHashMap<String, String>();
filterChainDefinitionManager.put("/logout", "logout");
filterChainDefinitionManager.put("/user/**", "authc,roles[ROLE_USER]");//用户为ROLE_USER 角色可以访问。由用户角色控制用户行为。
filterChainDefinitionManager.put("/events/**", "authc,roles[ROLE_ADMIN]");
// filterChainDefinitionManager.put("/user/edit/**", "authc,perms[user:edit]");// 这里为了测试,固定写死的值,也可以从数据库或其他配置中读取,此处是用权限控制
filterChainDefinitionManager.put("/**", "anon");
shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionManager);
shiroFilterFactoryBean.setSuccessUrl("/");
shiroFilterFactoryBean.setUnauthorizedUrl("/403");
return shiroFilterFactoryBean;
}
/**
* DefaultAdvisorAutoProxyCreator,Spring的一个bean,由Advisor决定对哪些类的方法进行AOP代理。
*/
@Bean
@ConditionalOnMissingBean
public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() {
DefaultAdvisorAutoProxyCreator defaultAAP = new DefaultAdvisorAutoProxyCreator();
defaultAAP.setProxyTargetClass(true);
return defaultAAP;
}
/**
* AuthorizationAttributeSourceAdvisor,shiro里实现的Advisor类,
* 内部使用AopAllianceAnnotationsAuthorizingMethodInterceptor来拦截用以下注解的方法。
*/
@Bean
public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor() {
AuthorizationAttributeSourceAdvisor aASA = new AuthorizationAttributeSourceAdvisor();
aASA.setSecurityManager(securityManager());
return aASA;
}
}
3. 添加Realm 验证
package com.us.shiro;
import com.us.bean.Permission;
import com.us.bean.Role;
import com.us.bean.User;
import com.us.dao.PermissionDao;
import com.us.dao.UserDao;
import org.apache.shiro.SecurityUtils;
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.session.Session;
import org.apache.shiro.subject.PrincipalCollection;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
/**
* Created by cdyoue on 2016/10/21.
*/
public class ShiroRealm extends AuthorizingRealm {
private Logger logger = LoggerFactory.getLogger(this.getClass());
@Autowired
private UserDao userService;
@Autowired
private PermissionDao permissionService;
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
logger.info("doGetAuthorizationInfo+"+principalCollection.toString());
User user = userService.getByUserName((String) principalCollection.getPrimaryPrincipal());
//把principals放session中 key=userId value=principals
SecurityUtils.getSubject().getSession().setAttribute(String.valueOf(user.getId()),SecurityUtils.getSubject().getPrincipals());
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
//赋予角色
for(Role userRole:user.getRoles()){
info.addRole(userRole.getName());
}
//赋予权限
for(Permission permission:permissionService.getByUserId(user.getId())){
// if(StringUtils.isNotBlank(permission.getPermCode()))
info.addStringPermission(permission.getName());
}
//设置登录次数、时间
// userService.updateUserLogin(user);
return info;
}
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
logger.info("doGetAuthenticationInfo +" + authenticationToken.toString());
UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken;
String userName=token.getUsername();
logger.info(userName+token.getPassword());
User user = userService.getByUserName(token.getUsername());
if (user != null) {
// byte[] salt = Encodes.decodeHex(user.getSalt());
// ShiroUser shiroUser=new ShiroUser(user.getId(), user.getLoginName(), user.getName());
//设置用户session
Session session = SecurityUtils.getSubject().getSession();
session.setAttribute("user", user);
return new SimpleAuthenticationInfo(userName,user.getPassword(),getName());
} else {
return null;
}
// return null;
}
}
4. 添加controller
package com.us.controller;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.*;
import java.util.HashMap;
import java.util.Map;
/**
* Created by cdyoue on 2016/10/21.
* 登陆控制器
*/
@RestController
public class LoginController {
private Logger logger = LoggerFactory.getLogger(this.getClass());
@RequestMapping(value = "/login", method = RequestMethod.POST)
public String login(
@RequestParam(value = "username", required = true) String userName,
@RequestParam(value = "password", required = true) String password,
@RequestParam(value = "rememberMe", required = true, defaultValue = "false") boolean rememberMe
) {
logger.info("==========" + userName + password + rememberMe);
Subject subject = SecurityUtils.getSubject();
UsernamePasswordToken token = new UsernamePasswordToken(userName, password);
token.setRememberMe(rememberMe);
try {
subject.login(token);
} catch (AuthenticationException e) {
e.printStackTrace();
// rediect.addFlashAttribute("errorText", "您的账号或密码输入错误!");
return "{\"Msg\":\"您的账号或密码输入错误\",\"state\":\"failed\"}";
}
return "{\"Msg\":\"登陆成功\",\"state\":\"success\"}";
}
@RequestMapping("/")
@ResponseBody
public String index() {
return "no permission";
}
}
此处代码不全,只是写了springboot 整合的主要类,如果需要全部代码请移步。。。
springboot集成shiro 实现权限控制(转)的更多相关文章
- SpringBoot集成Shiro实现权限控制
Shiro简介 Apache Shiro是一个功能强大且易于使用的Java安全框架,用于执行身份验证,授权,加密和会话管理.使用Shiro易于理解的API,您可以快速轻松地保护任何应用程序-从最小的移 ...
- springboot集成shiro实现权限认证
github:https://github.com/peterowang/shiro 基于上一篇:springboot集成shiro实现身份认证 1.加入UserController package ...
- SpringBoot整合Shiro实现权限控制,验证码
本文介绍 SpringBoot 整合 shiro,相对于 Spring Security 而言,shiro 更加简单,没有那么复杂. 目前我的需求是一个博客系统,有用户和管理员两种角色.一个用户可能有 ...
- SpringBoot整合Shiro实现权限控制
目录 1.SpringBoot整合Shiro 1.1.shiro简介 1.2.代码的具体实现 1.2.1.Maven的配置 1.2.2.整合需要实现的类 1.2.3.项目结构 1.2.4.ShiroC ...
- springboot集成shiro实现权限缓存和记住我
到这节为止,我们已经实现了身份验证和权限验证.但是,如果我们登录之后多次访问http://localhost:8080/userInfo/userDel的话,会发现权限验证会每次都执行一次.这是有问题 ...
- SpringBoot集成Shiro 实现动态加载权限
一.前言 本文小编将基于 SpringBoot 集成 Shiro 实现动态uri权限,由前端vue在页面配置uri,Java后端动态刷新权限,不用重启项目,以及在页面分配给用户 角色 . 按钮 .ur ...
- SpringBoot集成Shiro并用MongoDB做Session存储
之前项目鉴权一直使用的Shiro,那是在Spring MVC里面使用的比较多,而且都是用XML来配置,用Shiro来做权限控制相对比较简单而且成熟,而且我一直都把Shiro的session放在mong ...
- SpringBoot学习笔记(五):SpringBoot集成lombok工具、SpringBoot集成Shiro安全框架
SpringBoot集成lombok工具 什么是lombok? 自动生成setget方法,构造函数,打印日志 官网:http://projectlombok.org/features/index. 平 ...
- SpringBoot与Shiro整合权限管理实战
SpringBoot与Shiro整合权限管理实战 作者 : Stanley 罗昊 [转载请注明出处和署名,谢谢!] *观看本文章需要有一定SpringBoot整合经验* Shiro框架简介 Apach ...
随机推荐
- Codefroces Educational Round 27 845G Shortest Path Problem?
Shortest Path Problem? You are given an undirected graph with weighted edges. The length of some pat ...
- ES6第三节:变量的解构赋值
ES6允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这被称为解构.下面我们看实际的例子: 一.数组解构: let [a,b,c] = [1,2,3]; console.log(a); //a ...
- 程序中为什么会使用while(0)
https://blog.csdn.net/u012062760/article/details/46446207 关于while(0)实际上是用来宏定义的,这样的宏定义可以避免调用的时候出错. 如下 ...
- 【Pycharm】【HTML/jQuery】代码换行问题
问题:从网上下载jQuery文件后发现代码太长,不利于阅读:Pycharm没有预先设置好js文件的自动换行设置 问题 解决办法 解决后
- Highcharts图表的注解功能
Highcharts图表的注解功能 在图表中,往往须要对图表总体或者部分元素进行对应注解.帮助浏览者阅读图表.尽管标签组labels能够实现类似的功能.可是其功能相对简单.要实现复杂的注解功能,用户能 ...
- ubuntu终端sudo java提示“command not found”解决办法
我在ubuntu 12.04里想启动一个java程序,sudo java -jar xxx.jar,但是结果提示sudo:java:command not found. Ubuntu下用sudo运行j ...
- Leetcode47: Palindrome Linked List
Given a singly linked list, determine if it is a palindrome. 推断一个链表是不是回文的,一个比較简单的办法是把链表每一个结点的值存在vect ...
- Uniform Server
Uniform Server http://www.uniformserver.com/ https://sourceforge.net/projects/miniserver/files/ Unif ...
- jmeter响应数据中文乱码问题
进入jmeter安装文件目录:D:\Program File\apache-jmeter-2.13\apache-jmeter-2.13\bin\ 修改jmeter.properties文件,在最下方 ...
- Codeforces Round #193 (Div. 2) 部分题解
A:直接判断前三项是否相等 int main() { //FIN; //CHEAT; int n; cin>>n; getchar(); ]; gets(a); int len = str ...