shiro 之权限验证问题
1 shiro的配置,通过maven加入shiro相关jar包
- <!-- shiro -->
- <dependency>
- <groupId>org.apache.shiro</groupId>
- <artifactId>shiro-core</artifactId>
- <version>1.2.1</version>
- </dependency>
- <dependency>
- <groupId>org.apache.shiro</groupId>
- <artifactId>shiro-web</artifactId>
- <version>1.2.1</version>
- </dependency>
- <dependency>
- <groupId>org.apache.shiro</groupId>
- <artifactId>shiro-ehcache</artifactId>
- <version>1.2.1</version>
- </dependency>
- <dependency>
- <groupId>org.apache.shiro</groupId>
- <artifactId>shiro-spring</artifactId>
- <version>1.2.1</version>
- </dependency>
2 在web.xml中添加shiro过滤器
- <?xml version="1.0" encoding="UTF-8"?>
- <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:javaee="http://java.sun.com/xml/ns/javaee"
- xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
- xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
- id="WebApp_ID" version="2.4">
- <!-- 配置spring容器监听器 -->
- <span style="color:#ff6666;"> <context-param>
- <param-name>contextConfigLocation</param-name>
- <param-value>classpath:application-context-*.xml</param-value>
- </context-param>
- <listener>
- <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
- </listener></span>
- <!-- post乱码处理 -->
- <filter>
- <filter-name>CharacterEncodingFilter</filter-name>
- <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
- <init-param>
- <param-name>encoding</param-name>
- <param-value>utf-8</param-value>
- </init-param>
- </filter>
- <filter-mapping>
- <filter-name>CharacterEncodingFilter</filter-name>
- <url-pattern>/*</url-pattern>
- </filter-mapping>
- <!-- 配置shiro的核心拦截器 -->
- <span style="white-space:pre"> </span><filter>
- <filter-name>shiroFilter</filter-name>
- <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
- </filter>
- <filter-mapping>
- <filter-name>shiroFilter</filter-name>
- <url-pattern>/admin/*</url-pattern>
- </filter-mapping>
- <!-- 配置后台Springmvc 它拦截.do结尾的请求 -->
- <servlet>
- <servlet-name>back</servlet-name>
- <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
- <init-param>
- <param-name>contextConfigLocation</param-name>
- <param-value>classpath:springmvc.xml</param-value>
- </init-param>
- </servlet>
- <servlet-mapping>
- <servlet-name>back</servlet-name>
- <url-pattern>*.do</url-pattern>
- </servlet-mapping>
- <display-name>Archetype Created Web Application</display-name>
- </web-app>
3 spring中对shiro配置
-
<?xml
version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd"
default-lazy-init="true">
<description>Shiro Configuration</description>
<!-- 加载配置属性文件 -->
<context:property-placeholder ignore-unresolvable="true" location="classpath:jeesite.properties" />
<!-- Shiro权限过滤过滤器定义 -->
<bean name="shiroFilterChainDefinitions" class="java.lang.String">
<constructor-arg>
<value>
/static/** = anon
/userfiles/** = anon
${adminPath}/cas = cas
${adminPath}/login = authc
${adminPath}/logout = logout
${adminPath}/** = user
/act/rest/service/editor/** = perms[act:model:edit]
/act/rest/service/model/** = perms[act:model:edit]
/act/rest/service/** = user
/ReportServer/** = user
</value>
</constructor-arg>
</bean>
<!-- 安全认证过滤器 -->
<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
<property name="securityManager" ref="securityManager" /><!--
<property name="loginUrl" value="${cas.server.url}?service=${cas.project.url}${adminPath}/cas" /> -->
<property name="loginUrl" value="${adminPath}/login" />
<property name="successUrl" value="${adminPath}?login" />
<property name="filters">
<map>
<entry key="cas" value-ref="casFilter"/>
<entry key="authc" value-ref="formAuthenticationFilter"/>
</map>
</property>
<property name="filterChainDefinitions">
<ref bean="shiroFilterChainDefinitions"/>
</property>
</bean>
<!-- CAS认证过滤器 -->
<bean id="casFilter" class="org.apache.shiro.cas.CasFilter">
<property name="failureUrl" value="${adminPath}/login"/>
</bean>
<!-- 定义Shiro安全管理配置 -->
<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
<property name="realm" ref="systemAuthorizingRealm" />
<property name="sessionManager" ref="sessionManager" />
<property name="cacheManager" ref="shiroCacheManager" />
</bean>
<!-- 自定义会话管理配置 -->
<bean id="sessionManager" class="com.thinkgem.jeesite.common.security.shiro.session.SessionManager">
<property name="sessionDAO" ref="sessionDAO"/>
<!-- 会话超时时间,单位:毫秒 -->
<property name="globalSessionTimeout" value="${session.sessionTimeout}"/>
<!-- 定时清理失效会话, 清理用户直接关闭浏览器造成的孤立会话 -->
<property name="sessionValidationInterval" value="${session.sessionTimeoutClean}"/>
<!-- <property name="sessionValidationSchedulerEnabled" value="false"/> -->
<property name="sessionValidationSchedulerEnabled" value="true"/>
<property name="sessionIdCookie" ref="sessionIdCookie"/>
<property name="sessionIdCookieEnabled" value="true"/>
</bean>
<!-- 指定本系统SESSIONID, 默认为: JSESSIONID 问题: 与SERVLET容器名冲突, 如JETTY, TOMCAT 等默认JSESSIONID,
当跳出SHIRO SERVLET时如ERROR-PAGE容器会为JSESSIONID重新分配值导致登录会话丢失! -->
<bean id="sessionIdCookie" class="org.apache.shiro.web.servlet.SimpleCookie">
<constructor-arg name="name" value="jeesite.session.id"/>
</bean>
<!-- 自定义Session存储容器 -->
<!-- <bean id="sessionDAO" class="com.thinkgem.jeesite.common.security.shiro.session.JedisSessionDAO"> -->
<!-- <property name="sessionIdGenerator" ref="idGen" /> -->
<!-- <property name="sessionKeyPrefix" value="${redis.keyPrefix}_session_" /> -->
<!-- </bean> -->
<bean id="sessionDAO" class="com.thinkgem.jeesite.common.security.shiro.session.CacheSessionDAO">
<property name="sessionIdGenerator" ref="idGen" />
<property name="activeSessionsCacheName" value="activeSessionsCache" />
<property name="cacheManager" ref="shiroCacheManager" />
</bean>
<!-- 定义授权缓存管理器 -->
<!-- <bean id="shiroCacheManager" class="com.thinkgem.jeesite.common.security.shiro.cache.SessionCacheManager" /> -->
<bean id="shiroCacheManager" class="org.apache.shiro.cache.ehcache.EhCacheManager">
<property name="cacheManager" ref="cacheManager"/>
</bean>
<!-- 保证实现了Shiro内部lifecycle函数的bean执行 -->
<bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor"/>
<!-- AOP式方法级权限检查 -->
<bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator" depends-on="lifecycleBeanPostProcessor">
<property name="proxyTargetClass" value="true" />
</bean>
<bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">
<property name="securityManager" ref="securityManager"/>
</bean>
</beans>
其次,上面中的配置也是将credentialsMatcher没有加入了,这种方式适用于没有对密码进行处理的情况。
其中CustomRealm的配置是重点。
4 自定义Realm编码
CustomRealm如下:
自定义relam是shiro的核心代码之一,在这里做了认证授权
授权的做法就是查找该用户下的所有角色,并把角色相关的权限标识放到 授权信息 SimpleAuthorizationInfo 中就可以了
* Copyright © 2012-2014 <a href="https://www.mycomm.com/mycommcrm">MyComm CRM</a> All rights reserved.
*/
package com.thinkgem.jeesite.modules.sys.security;
import java.io.Serializable;
import java.util.Collection;
import java.util.List;
import javax.annotation.PostConstruct;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.Permission;
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.apache.shiro.subject.support.DefaultSubjectContext;
import org.apache.shiro.util.ByteSource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import com.thinkgem.jeesite.common.config.Global;
import com.thinkgem.jeesite.common.servlet.ValidateCodeServlet;
import com.thinkgem.jeesite.common.utils.Encodes;
import com.thinkgem.jeesite.common.utils.SpringContextHolder;
import com.thinkgem.jeesite.common.web.Servlets;
import com.thinkgem.jeesite.modules.sys.entity.Menu;
import com.thinkgem.jeesite.modules.sys.entity.Role;
import com.thinkgem.jeesite.modules.sys.entity.User;
import com.thinkgem.jeesite.modules.sys.service.SystemService;
import com.thinkgem.jeesite.modules.sys.utils.LogUtils;
import com.thinkgem.jeesite.modules.sys.utils.UserUtils;
import com.thinkgem.jeesite.modules.sys.web.LoginController;
/**
* 系统安全认证实现类
* @author MyComm
* @version 2014-7-5
*/
@Service
//@DependsOn({"userDao","roleDao","menuDao"})
public class SystemAuthorizingRealm extends AuthorizingRealm {
private Logger logger = LoggerFactory.getLogger(getClass());
private SystemService systemService;
/**
* 认证回调函数, 登录时调用
*/
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authcToken) {
UsernamePasswordToken token = (UsernamePasswordToken) authcToken;
int activeSessionSize = getSystemService().getSessionDao().getActiveSessions(false).size();
if (logger.isDebugEnabled()){
logger.debug("login submit, active session size: {}, username: {}, password: {}", activeSessionSize, token.getUsername(), token.getPassword());
}
// 校验登录验证码
if (LoginController.isValidateCodeLogin(token.getUsername(), false, false)){
Session session = UserUtils.getSession();
String code = (String)session.getAttribute(ValidateCodeServlet.VALIDATE_CODE);
if (token.getCaptcha() == null || !token.getCaptcha().toUpperCase().equals(code)){
throw new AuthenticationException("msg:验证码错误, 请重试.");
}
}
// 校验用户名密码
User user = getSystemService().getUserByLoginName(token.getUsername());
if (user != null) {
if (Global.NO.equals(user.getLoginFlag())){
throw new AuthenticationException("msg:该已帐号禁止登录.");
}
byte[] salt = Encodes.decodeHex(user.getPassword().substring(0,16));
SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(new Principal(user, token.isMobileLogin(), token.getExtNum(),token.getIsReady(),token.getIsCheckin(),token.getSeatTel()),
user.getPassword().substring(16), ByteSource.Util.bytes(salt), getName());
return authenticationInfo;
} else {
return null;
}
}
/**
* 授权查询回调函数, 进行鉴权但缓存中无用户的授权信息时调用
*/
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
Principal principal = (Principal) getAvailablePrincipal(principals);
// 获取当前已登录的用户
if (!Global.TRUE.equals(Global.getConfig("user.multiAccountLogin"))){
Collection<Session> sessions = getSystemService().getSessionDao().getActiveSessions(true, principal, UserUtils.getSession());
if (sessions.size() > 0){
// 如果是登录进来的,则踢出已在线用户
if (UserUtils.getSubject().isAuthenticated()){
User user = new User();
for (Session session : sessions){
if(session.getAttribute(DefaultSubjectContext.PRINCIPALS_SESSION_KEY)!=null){
user= UserUtils.get(session.getAttribute(DefaultSubjectContext.PRINCIPALS_SESSION_KEY).toString());
}
if(null!=user && null!=principal && (principal.getId()).equals(user.getId())){
getSystemService().getSessionDao().delete(session);
}
}
}
// 记住我进来的,并且当前用户已登录,则退出当前用户提示信息。
else{
UserUtils.getSubject().logout();
throw new AuthenticationException("msg:账号已在其它地方登录,请重新登录。");
}
}
}
User user = getSystemService().getUserByLoginName(principal.getLoginName());
if (user != null) {
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
List<Menu> list = UserUtils.getMenuList();
for (Menu menu : list){
if (StringUtils.isNotBlank(menu.getPermission())){
// 添加基于Permission的权限信息
for (String permission : StringUtils.split(menu.getPermission(),",")){
info.addStringPermission(permission);
}
}
}
// 添加用户权限
info.addStringPermission("user");
// 添加用户角色信息
for (Role role : user.getRoleList()){
info.addRole(role.getEnname());
}
// 更新登录IP和时间
getSystemService().updateUserLoginInfo(user);
// 记录登录日志
LogUtils.saveLog(Servlets.getRequest(), "系统登录");
return info;
} else {
return null;
}
}
@Override
protected void checkPermission(Permission permission, AuthorizationInfo info) {
authorizationValidate(permission);
super.checkPermission(permission, info);
}
@Override
protected boolean[] isPermitted(List<Permission> permissions, AuthorizationInfo info) {
if (permissions != null && !permissions.isEmpty()) {
for (Permission permission : permissions) {
authorizationValidate(permission);
}
}
return super.isPermitted(permissions, info);
}
@Override
public boolean isPermitted(PrincipalCollection principals, Permission permission) {
authorizationValidate(permission);
return super.isPermitted(principals, permission);
}
@Override
protected boolean isPermittedAll(Collection<Permission> permissions, AuthorizationInfo info) {
if (permissions != null && !permissions.isEmpty()) {
for (Permission permission : permissions) {
authorizationValidate(permission);
}
}
return super.isPermittedAll(permissions, info);
}
/**
* 授权验证方法
* @param permission
*/
private void authorizationValidate(Permission permission){
// 模块授权预留接口
}
/**
* 设定密码校验的Hash算法与迭代次数
*/
@PostConstruct
public void initCredentialsMatcher() {
HashedCredentialsMatcher matcher = new HashedCredentialsMatcher(SystemService.HASH_ALGORITHM);
matcher.setHashIterations(SystemService.HASH_INTERATIONS);
setCredentialsMatcher(matcher);
}
///**
//* 清空用户关联权限认证,待下次使用时重新加载
//*/
//public void clearCachedAuthorizationInfo(Principal principal) {
//SimplePrincipalCollection principals = new SimplePrincipalCollection(principal, getName());
//clearCachedAuthorizationInfo(principals);
//}
/**
* 清空所有关联认证
* @Deprecated 不需要清空,授权缓存保存到session中
*/
@Deprecated
public void clearAllCachedAuthorizationInfo() {
//Cache<Object, AuthorizationInfo> cache = getAuthorizationCache();
//if (cache != null) {
//for (Object key : cache.keys()) {
//cache.remove(key);
//}
//}
}
/**
* 获取系统业务对象
*/
public SystemService getSystemService() {
if (systemService == null){
systemService = SpringContextHolder.getBean(SystemService.class);
}
return systemService;
}
/**
* 授权用户信息
*/
public static class Principal implements Serializable {
private static final long serialVersionUID = 1L;
private String id; // 编号
private String loginName; // 登录名
private String name; // 姓名
private String extNum; //分机
private String isReady; //自动就绪
private String isCheckin; //自动签入
private String seatTel; //座席电话
private boolean mobileLogin; // 是否手机登录
//private Map<String, Object> cacheMap;
public Principal(User user, boolean mobileLogin, String extNum, String isReady, String isCheckin,String seatTel) {
this.id = user.getId();
this.loginName = user.getLoginName();
this.name = user.getName();
this.mobileLogin = mobileLogin;
this.extNum = extNum;
this.isReady = isReady;
this.isCheckin = isCheckin;
this.seatTel = seatTel;
}
public String getId() {
return id;
}
public String getLoginName() {
return loginName;
}
public String getName() {
return name;
}
public String getExtNum() {
return extNum;
}
public String getIsReady() {
return isReady;
}
public String getIsCheckin() {
return isCheckin;
}
public String getSeatTel() {
return seatTel;
}
public void setSeatTel(String seatTel) {
this.seatTel = seatTel;
}
public boolean isMobileLogin() {
return mobileLogin;
}
//@JsonIgnore
//public Map<String, Object> getCacheMap() {
//if (cacheMap==null){
//cacheMap = new HashMap<String, Object>();
//}
//return cacheMap;
//}
/**
* 获取SESSIONID
*/
public String getSessionid() {
try{
return (String) UserUtils.getSession().getId();
}catch (Exception e) {
return "";
}
}
@Override
public String toString() {
return id;
}
}
}
- }
5 缓存配置
ehcache.xml代码如下:
- <ehcache updateCheck="false" name="shiroCache">
- <defaultCache
- maxElementsInMemory="10000"
- eternal="false"
- timeToIdleSeconds="120"
- timeToLiveSeconds="120"
- overflowToDisk="false"
- diskPersistent="false"
- diskExpiryThreadIntervalSeconds="120"
- />
- </ehcache>
6.自定义表单编码过滤器
CustomFormAuthenticationFilter代码,认证之前调用,可用于验证码校验
- public class CustomFormAuthenticationFilter extends FormAuthenticationFilter {
- // 原FormAuthenticationFilter的认证方法
- @Override
- protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception {
- // 在这里进行验证码的校验
- // 从session获取正确验证码
- HttpServletRequest httpServletRequest = (HttpServletRequest) request;
- HttpSession session = httpServletRequest.getSession();
- // 取出session的验证码(正确的验证码)
- String validateCode = (String) session.getAttribute("validateCode");
- // 取出页面的验证码
- // 输入的验证和session中的验证进行对比
- String randomcode = httpServletRequest.getParameter("randomcode");
- if (randomcode != null && validateCode != null && !randomcode.equals(validateCode)) {
- // 如果校验失败,将验证码错误失败信息,通过shiroLoginFailure设置到request中
- httpServletRequest.setAttribute("shiroLoginFailure", "randomCodeError");
- // 拒绝访问,不再校验账号和密码
- return true;
- }
- return super.onAccessDenied(request, response);
- }
- }
在此符上验证码jsp界面的代码
validatecode.jsp
- <%@ page language="java" contentType="text/html; charset=UTF-8"
- pageEncoding="UTF-8"%>
- <%@ page import="java.util.Random"%>
- <%@ page import="java.io.OutputStream"%>
- <%@ page import="java.awt.Color"%>
- <%@ page import="java.awt.Font"%>
- <%@ page import="java.awt.Graphics"%>
- <%@ page import="java.awt.image.BufferedImage"%>
- <%@ page import="javax.imageio.ImageIO"%>
- <%
- int width = 60;
- int height = 32;
- //create the image
- BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
- Graphics g = image.getGraphics();
- // set the background color
- g.setColor(new Color(0xDCDCDC));
- g.fillRect(0, 0, width, height);
- // draw the border
- g.setColor(Color.black);
- g.drawRect(0, 0, width - 1, height - 1);
- // create a random instance to generate the codes
- Random rdm = new Random();
- String hash1 = Integer.toHexString(rdm.nextInt());
- // make some confusion
- for (int i = 0; i < 50; i++) {
- int x = rdm.nextInt(width);
- int y = rdm.nextInt(height);
- g.drawOval(x, y, 0, 0);
- }
- // generate a random code
- String capstr = hash1.substring(0, 4);
- //将生成的验证码存入session
- session.setAttribute("validateCode", capstr);
- g.setColor(new Color(0, 100, 0));
- g.setFont(new Font("Candara", Font.BOLD, 24));
- g.drawString(capstr, 8, 24);
- g.dispose();
- //输出图片
- response.setContentType("image/jpeg");
- out.clear();
- out = pageContext.pushBody();
- OutputStream strm = response.getOutputStream();
- ImageIO.write(image, "jpeg", strm);
- strm.close();
- %>
7.登录控制器方法
- /**
- * 到登录界面
- *
- * @return
- * @throws Exception
- */
- @RequestMapping("login.do")
- public String adminPage(HttpServletRequest request) throws Exception {
- // 如果登陆失败从request中获取认证异常信息,shiroLoginFailure就是shiro异常类的全限定名
- String exceptionClassName = (String) request.getAttribute("shiroLoginFailure");
- // 根据shiro返回的异常类路径判断,抛出指定异常信息
- if (exceptionClassName != null) {
- if (UnknownAccountException.class.getName().equals(exceptionClassName)) {
- // 最终会抛给异常处理器
- throw new CustomJsonException("账号不存在");
- } else if (IncorrectCredentialsException.class.getName().equals(exceptionClassName)) {
- throw new CustomJsonException("用户名/密码错误");
- } else if ("randomCodeError".equals(exceptionClassName)) {
- throw new CustomJsonException("验证码错误 ");
- } else {
- throw new Exception();// 最终在异常处理器生成未知错误
- }
- }
- // 此方法不处理登陆成功(认证成功),shiro认证成功会自动跳转到上一个请求路径
- // 登陆失败还到login页面
- return "admin/login";
- }
8.用户回显Controller
当用户登录认证成功后,CustomRealm在调用完doGetAuthenticationInfo时,通过
- AuthenticationInfo authcInfo = new SimpleAuthenticationInfo(adminUser, password, this.getName());
- return authcInfo;
所以需要回显用户信息时,我这样调用的
- @RequestMapping("index.do")
- public String index(Model model) {
- //从shiro的session中取activeUser
- Subject subject = SecurityUtils.getSubject();
- //取身份信息
- TAdminUser adminUser = (TAdminUser) subject.getPrincipal();
- //通过model传到页面
- model.addAttribute("adminUser", adminUser);
- return "admin/index";
- }
9.在jsp页面中控制权限
先引入shiro的头文件
- <!-- shiro头引入 -->
- <%@ taglib uri="http://shiro.apache.org/tags" prefix="shiro"%>
采用shiro标签对权限进行处理
- <!-- 有curd权限才显示修改链接,没有该 权限不显示,相当 于if(hasPermission(curd)) -->
- <shiro:hasPermission name="curd">
- <BR />
- 我拥有超级的增删改查权限额
- </shiro:hasPermission>
10.在Controller控制权限
通过@RequiresPermissions注解,指定执行此controller中某个请求方法需要的权限
-
@RequiresPermissions("sys:role:edit")
//需要有修改角色的权限
@RequestMapping(value = "delete")
public String delete(Role role, RedirectAttributes redirectAttributes,HttpServletRequest request) {
11.MD5加密加盐处理
这里以修改密码为例,通过获取新的密码(明文)后通过MD5加密+加盐+6次加密为例
- @RequestMapping("updatePassword.do")
- @ResponseBody
- public String updateAdminUserPassword(String newPassword) {
- // 从shiro的session中取activeUser
- Subject subject = SecurityUtils.getSubject();
- // 取身份信息
- TAdminUser adminUser = (TAdminUser) subject.getPrincipal();
- // 生成salt,随机生成
- SecureRandomNumberGenerator secureRandomNumberGenerator = new SecureRandomNumberGenerator();
- String salt = secureRandomNumberGenerator.nextBytes().toHex();
- Md5Hash md5 = new Md5Hash(newPassword, salt, 6);
- String newMd5Password = md5.toHex();
- // 设置新密码
- adminUser.setPassword(newMd5Password);
- // 设置盐
- adminUser.setSalt(salt);
- adminUserService.updateAdminUserPassword(adminUser);
- return newPassword;
- }
这是菜单权限树,想为哪个角色赋什么样的权限只需勾选相应的按钮就可以了。(下一篇说说我总结的数据范围过滤)
相关推荐
- 验证码绕过之服务端相关问题
- X-Pack权限控制之给Kibana加上登录控制以及index_not_found_exception问题解决
- springboot2.0+shiro1.4.0权限过滤不生效问题
- Winform通用框架之权限管理系统---数据连接出错问题
- 《分销系统-原创第一章》之“多用户角色权限访问模块问题”的解决思路( 位运算 + ActionFilterAttribute )...
- 成长记录贴之springboot+shiro(二) {完成一个完整的权限控制,详细步骤}
- springboot shiro权限管理【三】:测试框架搭建之shiro授权
- MySQL数据库学习日志之Day03_数据库远程连接权限问题
- 4、Shiro之IniRealm以及用户登录认证,角色认证,权限认证
- shiro之权限过滤
- python入门教程完整版(懂中文就能学会)-Python入门教程完整版400集(懂中文就能学会)快来带走...
- 针对一个密集域,多个稀疏域的跨域推荐