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. C++的new_handler

    这个new_handler其实对应于signal_handler 当operator new申请一个内存失败时,它会进行如下的处理步骤:1.如果存在客户指定的处理函数,则调用处理函数(new_hand ...

  2. C/C++获取本地时间常见方法

    跨平台方法 方法一:手动暴力法 #include <iostream> using namespace std; #include <time.h> time_t t = ti ...

  3. 61.node.js开发错误——Error: Connection strategy not found

    转自:https://blog.csdn.net/fd214333890/article/details/53457145

  4. Impala性能优化

    不多说,直接上干货! • 执行计划 – 查询sql执行之前,先对该sql做一个分析,列出需要完成这一项查询的详细方案 – 命令:explain sql.profile 要点: • 1.SQL优化,使用 ...

  5. Codefroces Educational Round 27 (A,B,C,D)

    A. Chess Tourney time limit per test 1 second memory limit per test 256 megabytes input standard inp ...

  6. myBatis通过逗号分隔字符串,foreach

    前言 当数据库里存储的值是以逗号分隔格式存储的字符串时. 数据格式如下:  id name  ids   1  张三  a,b,c  2  李四  c,d,e 我们拿到的条件参数是:b,e 1.后台通 ...

  7. 单调栈+贪心维护LIS

    普通:O(\(N^2\)) 状态:dp[j]表示,以j结尾的最长的上升子序列 转移:dp[j]=dp[i]+1(if a[j]>a[i] ) 初始化:dp[i]=1 优化(nlogn) solu ...

  8. open阶段的一致性检验(二)

    SQL> select * from v$version where rownum=1; BANNER --------------------------------------------- ...

  9. funuiTitle-居中问题修改

    今天遇到了一个问题,在一个actionbar上,title居中了,现在想要的方式是,让actionbar上显示返回按钮,后面紧跟着title.当时自己一直尝试要找到activity,然后在theme中 ...

  10. Android学习笔记进阶十二之裁截图片

    package xiaosi.cut; import java.io.File; import android.app.Activity; import android.content.Intent; ...