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. 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 ...

  2. ES6第三节:变量的解构赋值

    ES6允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这被称为解构.下面我们看实际的例子: 一.数组解构: let [a,b,c] = [1,2,3]; console.log(a); //a ...

  3. 程序中为什么会使用while(0)

    https://blog.csdn.net/u012062760/article/details/46446207 关于while(0)实际上是用来宏定义的,这样的宏定义可以避免调用的时候出错. 如下 ...

  4. 【Pycharm】【HTML/jQuery】代码换行问题

    问题:从网上下载jQuery文件后发现代码太长,不利于阅读:Pycharm没有预先设置好js文件的自动换行设置 问题 解决办法 解决后

  5. Highcharts图表的注解功能

    Highcharts图表的注解功能 在图表中,往往须要对图表总体或者部分元素进行对应注解.帮助浏览者阅读图表.尽管标签组labels能够实现类似的功能.可是其功能相对简单.要实现复杂的注解功能,用户能 ...

  6. ubuntu终端sudo java提示“command not found”解决办法

    我在ubuntu 12.04里想启动一个java程序,sudo java -jar xxx.jar,但是结果提示sudo:java:command not found. Ubuntu下用sudo运行j ...

  7. Leetcode47: Palindrome Linked List

    Given a singly linked list, determine if it is a palindrome. 推断一个链表是不是回文的,一个比較简单的办法是把链表每一个结点的值存在vect ...

  8. Uniform Server

    Uniform Server http://www.uniformserver.com/ https://sourceforge.net/projects/miniserver/files/ Unif ...

  9. jmeter响应数据中文乱码问题

    进入jmeter安装文件目录:D:\Program File\apache-jmeter-2.13\apache-jmeter-2.13\bin\ 修改jmeter.properties文件,在最下方 ...

  10. Codeforces Round #193 (Div. 2) 部分题解

    A:直接判断前三项是否相等 int main() { //FIN; //CHEAT; int n; cin>>n; getchar(); ]; gets(a); int len = str ...