springboot + shiro 简单实例

本文属于原创,说明简介,如果有问题,可留言一起探讨

1.搭建springboot项目,这里不做概述
2.引入shiro 依赖
<!-- apache shiro 权限框架 -->
< dependency >
< groupId > org.apache.shiro </ groupId >
< artifactId > shiro-spring </ artifactId >
< version > 1.4.0 </ version >
</ dependency >

3.创建 ShiroRealm
package wx.milk.web.controller.admin;

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.subject.PrincipalCollection;
import org.springframework.beans.factory.annotation. Autowired ;
import org.springframework.stereotype. Component ;
import wx.milk.service.admin.IUserService;
import wx.milk.web.utils.SpringBeanFactoryUtils;
import wx.query.Query;
import wx.query.Statement;
import wx.security.User;

import java.util.HashSet;
import java.util.Set;

/**
* Created by zhong.h on 2018/6/13/013.
*/
@Component
public class ShiroRealm extends AuthorizingRealm {

@Autowired
private IUserService service ;

/* 认证 . 登录 */
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
if ( service == null ) {
service = SpringBeanFactoryUtils. getBean (IUserService. class );
}
UsernamePasswordToken userToken = (UsernamePasswordToken) token; // 获取用户输入的 token

String account = userToken.getUsername();

Query query = new Query();
Statement statement = new Statement();
statement.setName( "account" );
statement.setValue(account);
query.and(statement);
User user = service .findByParam(query);
return new SimpleAuthenticationInfo(user, user.getPassword(), this .getClass().getName()); // 放入 shiro. 调用 CredentialsMatcher 检验密码
}

/**
* 授权用户权限
*/
@Override
protected AuthorizationInfo doGetAuthorizationInfo(
PrincipalCollection principals) {
// 获取用户
User user = (User) SecurityUtils. getSubject ().getPrincipal();
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
// 获取用户角色
Set<String> roleSet = new HashSet<String>();
roleSet.add( "100002" );
info.setRoles(roleSet);

// 获取用户权限
Set<String> permissionSet = new HashSet<String>();
permissionSet.add( " 权限添加 " );
permissionSet.add( " 权限删除 " );
info.setStringPermissions(permissionSet);


return info;
}
}


4.创建configuration
package wx.milk.web.configuration;

import org.apache.shiro.codec.Base64;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.CookieRememberMeManager;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.apache.shiro.web.servlet.SimpleCookie;
import org.springframework.context.annotation. Bean ;
import org.springframework.context.annotation. Configuration ;
import wx.milk.web.controller.admin.ShiroRealm;

import javax.servlet.Filter;
import java.util.LinkedHashMap;
import java.util.Map;

/**
* Created by zhong.h on 2018/6/13/013.
*/
@Configuration
public class ShiroConfiguration {

public ShiroRealm shiroRealm(){
return new ShiroRealm();
}

/**
* ShiroFilterFactoryBean 处理拦截资源文件问题。
* 注意:单独一个 ShiroFilterFactoryBean 配置是或报错的,以为在
* 初始化 ShiroFilterFactoryBean 的时候需要注入: SecurityManager
*
* Filter Chain 定义说明 1 、一个 URL 可以配置多个 Filter ,使用逗号分隔
* 2 、当设置多个过滤器时,全部验证通过,才视为通过
* 3 、部分过滤器可指定参数,如 perms roles
*
*/
@Bean
public ShiroFilterFactoryBean shiroFilter(DefaultWebSecurityManager securityManager) {
ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();

// 必须设置 SecurityManager
shiroFilterFactoryBean.setSecurityManager(securityManager);

// 如果不设置默认会自动寻找 Web 工程根目录下的 "/login.jsp" 页面
shiroFilterFactoryBean.setLoginUrl( "/admin/login" );
// 登录成功后要跳转的链接
shiroFilterFactoryBean.setSuccessUrl( "/admin/index" );
// 未授权界面 ;
shiroFilterFactoryBean.setUnauthorizedUrl( "/error" );

// 自定义拦截器
Map<String, Filter> filtersMap = new LinkedHashMap<String, Filter>();
// 限制同一帐号同时在线的个数。
//filtersMap.put("kickout", kickoutSessionControlFilter());
shiroFilterFactoryBean.setFilters(filtersMap);

// 权限控制 map.
Map<String, String> filterChainDefinitionMap = new LinkedHashMap<String, String>();
// 配置不会被拦截的链接 顺序判断
// 配置退出过滤器 , 其中的具体的退出代码 Shiro 已经替我们实现了
// 从数据库获取动态的权限
// filterChainDefinitionMap.put("/add", "perms[ 权限添加 ]");
// <!-- 过滤链定义,从上向下顺序执行,一般将 /** 放在最为下边 -->: 这是一个坑呢,一不小心代码就不好使了 ;
// <!-- authc: 所有 url 都必须认证通过才可以访问 ; anon: 所有 url 都都可以匿名访问 -->
//logout 这个拦截器是 shiro 已经实现好了的。
// 从数据库获取
/*List<SysPermissionInit> list = sysPermissionInitService.selectAll();

for (SysPermissionInit sysPermissionInit : list) {
filterChainDefinitionMap.put(sysPermissionInit.getUrl(),
sysPermissionInit.getPermissionInit());
}*/

shiroFilterFactoryBean
.setFilterChainDefinitionMap(filterChainDefinitionMap);
return shiroFilterFactoryBean;
}

@Bean
public DefaultWebSecurityManager securityManager() {
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
// 设置 realm.
securityManager.setRealm(shiroRealm());
// 自定义缓存实现 使用 redis
//securityManager.setCacheManager(cacheManager());
// 自定义 session 管理 使用 redis
//securityManager.setSessionManager(sessionManager());
// 注入记住我管理器 ;
securityManager.setRememberMeManager(rememberMeManager());
return securityManager;
}

/**
* cookie 对象 ;
* @return
*/
public SimpleCookie rememberMeCookie(){
// 这个参数是 cookie 的名称,对应前端的 checkbox name = rememberMe
SimpleCookie simpleCookie = new SimpleCookie( "rememberMe" );
//<!-- 记住我 cookie 生效时间 30 , 单位秒 ;-->
simpleCookie.setMaxAge( 2592000 );
return simpleCookie;
}

/**
* cookie 管理对象 ; 记住我功能
* @return
*/
public CookieRememberMeManager rememberMeManager(){
CookieRememberMeManager cookieRememberMeManager = new CookieRememberMeManager();
cookieRememberMeManager.setCookie(rememberMeCookie());
//rememberMe cookie 加密的密钥 建议每个项目都不一样 默认 AES 算法 密钥长度 (128 256 512 )
cookieRememberMeManager.setCipherKey(Base64. decode ( "3AvVhmFLUs0KTA3Kprsdag==" ));
return cookieRememberMeManager;
}
}

5. 测试
@RequestMapping (value = "/signin" )
public String login(HttpServletRequest request, HttpSession session,
String account, String password, String validatecode)
throws JsonManagerException {

String exception = (String) request.getAttribute( "shiroLoginFailure" );
if (StringUtils. isEmpty (account) || StringUtils. isEmpty (password)) {
return null ;
}

try {
UsernamePasswordToken token = new UsernamePasswordToken(account, password);
Subject subject = SecurityUtils. getSubject ();
subject.login(token);

User user=(User) subject.getPrincipal();
session.setAttribute( "user" , user);

return "/admin/index" ;
} catch (Exception e) {
logger .error(e.getMessage(), e);
throw e;
}

6。重要工具类
package wx.milk.web.utils;

import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype. Component ;

/**
* spring 加载时候,注入的 bean 的顺序是 先是 Lisener 然后是 Filter 最后是 Servlet
* 因此如果在过滤器或者监听器里面注入 service 等会是空,因为在过滤器或者监听器加载的时候
* Servlet service 等还没有加载,因此是空的,所以就手动注入
*
* Created by zhong.h on 2018/6/13/013.
*/
@Component
public class SpringBeanFactoryUtils implements ApplicationContextAware {

private static ApplicationContext applicationContext ;

@Override
public void setApplicationContext(ApplicationContext applicationContext)
throws BeansException {
if (SpringBeanFactoryUtils. applicationContext == null ) {
SpringBeanFactoryUtils. applicationContext = applicationContext;
}

}

public static ApplicationContext getApplicationContext() {
return applicationContext ;
}

// 根据名称( @Resource 注解)
public static Object getBean(String name) {
return getApplicationContext ().getBean(name);
}

// 根据类型( @Autowired
public static < T > T getBean(Class< T > clazz) {
return getApplicationContext ().getBean(clazz);
}

public static < T > T getBean(String name, Class< T > clazz) {
return getApplicationContext ().getBean(name, clazz);
}

}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值