您的位置:首页 > 其它

shiro 之权限验证问题

2017-10-12 11:54 459 查看

1 shiro的配置,通过maven加入shiro相关jar包

[html] view
plain copy

<!-- 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&
24000
gt;

</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过滤器

[html] view
plain copy

<?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配置

[html] view
plain copy

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

在上面的配置中每次开启了sessionManager都会出问题在这里将它注释掉了。

其次,上面中的配置也是将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代码如下:

[html] view
plain copy

<ehcache updateCheck="false" name="shiroCache">

<defaultCache

maxElementsInMemory="10000"

eternal="false"

timeToIdleSeconds="120"

timeToLiveSeconds="120"

overflowToDisk="false"

diskPersistent="false"

diskExpiryThreadIntervalSeconds="120"

/>

</ehcache>

通过使用ehache中就避免第次都向服务器发送权限授权(doGetAuthorizationInfo)的请求。

6.自定义表单编码过滤器

CustomFormAuthenticationFilter代码,认证之前调用,可用于验证码校验

[java] view
plain copy

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

[html] view
plain copy

<%@ 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.登录控制器方法

[java] view
plain copy

/**

* 到登录界面

*

* @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时,通过

[java] view
plain copy

AuthenticationInfo authcInfo = new SimpleAuthenticationInfo(adminUser, password, this.getName());

return authcInfo;

SimpleAuthenticationInfo构造参数的第一个参数传入一个用户的对象,之后,可通过Subject subject = SecurityUtils.getSubject();中的subject.getPrincipal()获取到此对象。

所以需要回显用户信息时,我这样调用的

[java] view
plain copy

@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的头文件

[html] view
plain copy

<!-- shiro头引入 -->

<%@ taglib uri="http://shiro.apache.org/tags" prefix="shiro"%>

采用shiro标签对权限进行处理

[html] view
plain copy

<!-- 有curd权限才显示修改链接,没有该 权限不显示,相当 于if(hasPermission(curd)) -->

<shiro:hasPermission name="curd">

<BR />

我拥有超级的增删改查权限额

</shiro:hasPermission>

10.在Controller控制权限

通过@RequiresPermissions注解,指定执行此controller中某个请求方法需要的权限

[java] view
plain copy

@RequiresPermissions("sys:role:edit")
//需要有修改角色的权限

@RequestMapping(value = "delete")

public String delete(Role role, RedirectAttributes redirectAttributes,HttpServletRequest request) {

11.MD5加密加盐处理

这里以修改密码为例,通过获取新的密码(明文)后通过MD5加密+加盐+6次加密为例

[java] view
plain copy

@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;

}

这是菜单权限树,想为哪个角色赋什么样的权限只需勾选相应的按钮就可以了。(下一篇说说我总结的数据范围过滤)

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  shiro