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 整合的主要类,如果需要全部代码请移步。。。

源码:https://github.com/527515025/springBoot

springboot集成shiro 实现权限控制(转)的更多相关文章

  1. SpringBoot集成Shiro实现权限控制

    Shiro简介 Apache Shiro是一个功能强大且易于使用的Java安全框架,用于执行身份验证,授权,加密和会话管理.使用Shiro易于理解的API,您可以快速轻松地保护任何应用程序-从最小的移 ...

  2. springboot集成shiro实现权限认证

    github:https://github.com/peterowang/shiro 基于上一篇:springboot集成shiro实现身份认证 1.加入UserController package ...

  3. SpringBoot整合Shiro实现权限控制,验证码

    本文介绍 SpringBoot 整合 shiro,相对于 Spring Security 而言,shiro 更加简单,没有那么复杂. 目前我的需求是一个博客系统,有用户和管理员两种角色.一个用户可能有 ...

  4. SpringBoot整合Shiro实现权限控制

    目录 1.SpringBoot整合Shiro 1.1.shiro简介 1.2.代码的具体实现 1.2.1.Maven的配置 1.2.2.整合需要实现的类 1.2.3.项目结构 1.2.4.ShiroC ...

  5. springboot集成shiro实现权限缓存和记住我

    到这节为止,我们已经实现了身份验证和权限验证.但是,如果我们登录之后多次访问http://localhost:8080/userInfo/userDel的话,会发现权限验证会每次都执行一次.这是有问题 ...

  6. SpringBoot集成Shiro 实现动态加载权限

    一.前言 本文小编将基于 SpringBoot 集成 Shiro 实现动态uri权限,由前端vue在页面配置uri,Java后端动态刷新权限,不用重启项目,以及在页面分配给用户 角色 . 按钮 .ur ...

  7. SpringBoot集成Shiro并用MongoDB做Session存储

    之前项目鉴权一直使用的Shiro,那是在Spring MVC里面使用的比较多,而且都是用XML来配置,用Shiro来做权限控制相对比较简单而且成熟,而且我一直都把Shiro的session放在mong ...

  8. SpringBoot学习笔记(五):SpringBoot集成lombok工具、SpringBoot集成Shiro安全框架

    SpringBoot集成lombok工具 什么是lombok? 自动生成setget方法,构造函数,打印日志 官网:http://projectlombok.org/features/index. 平 ...

  9. SpringBoot与Shiro整合权限管理实战

    SpringBoot与Shiro整合权限管理实战 作者 : Stanley 罗昊 [转载请注明出处和署名,谢谢!] *观看本文章需要有一定SpringBoot整合经验* Shiro框架简介 Apach ...

随机推荐

  1. POJ 2352 Stars(线段树)

    题目地址:id=2352">POJ 2352 今天的周赛被虐了. . TAT..线段树太渣了..得好好补补了(尽管是从昨天才開始学的..不能算补...) 这题还是非常easy的..维护 ...

  2. Your Ruby version is 2.2.3, but your Gemfile specified 2.2.2

    在文章 Ruby On Rails中REST API使用演示样例--基于云平台+云服务打造自己的在线翻译工具 中,从Bluemix上下载的初始Hello World演示样例代码在本地环境下运行调试时提 ...

  3. Image与byte[]数组的相互转换

         近期项目有个需求是关于图片操作的,须要将图片保存到数据库中.经过尝试才知道Image类型文件是不能直接存储到数据库中的.保存之前须要我们做一步转换:将Image转换成字节数组类型Byte ...

  4. RTSP、HTTP、HTTPS、SDP四种协议详解

    我们将主要讲解RTSP,HTTP,HTTPS, SDP四种协议.  一:RTSP协议简介 实时流协议RTSP是一个应用层协议,用于控制具有实时特性的数据(例如多媒体流)的传送. RTSP协议一般与RT ...

  5. java为什么要定义接口等相关解释

    1.接口的作用是实现多重继承  因为只能继承一个类(规定的) 2.一个类只能继承一个父类,但是可以实现一个或多个接口 3.abstract关键词能让你在类里创建一个或多个没有定义的方法—你给出接口,但 ...

  6. Android ijkplayer详解使用教程

    1.认识ijkplayer 最近公司准备开发一款视频播放及直播的应用,找了许多开源的框架,大部分都是基于ffmpeg开发的.最开始准备用Vitamio框架开发的,相关的文章也比较丰富,结果对于非个人移 ...

  7. Kinect 开发 —— Kinect for windows SDK

    开发 —— 基本的SDK和Windows 编程技巧(彩色图像视频流,深度图像视频流的采集,骨骼跟踪,音频处理,语音识别API) 深度数据,就是Kinect的精髓和灵魂,很多问题都转换为深度图像的模式识 ...

  8. Linux下关机命令的区别 (halt,poweroff,reboot,shutdown,init)

    1.shutdown shutdown命令安全地将系统关机.    而在系统关机前使用shutdown命令﹐系统管理员会通知所有登录的用户系统将要关闭.并且login指令会被冻结﹐即新的用户不能再登录 ...

  9. 03011_预处理对象executeUpdate方法(实现数据库的增、删、改)

    1.概述 (1)通过预处理对象的executeUpdate方法,完成记录的insert\update\delete语句的执行: (2)操作格式统一如下: ①注册驱动: ②获取连接: ③获取预处理对象: ...

  10. 【习题 8-1 UVA - 1149】Bin Packing

    [链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 每个背包只能装两个东西. 而且每个东西都要被装进去. 那么我们随意考虑某个物品.(不必要求顺序 这个物品肯定要放进某个背包里面的. ...