Shiro的Web项目配置(转)
Shiro的Web项目配置
一 shiro的学习
二 shiro的java客户端配置
三 关于权限的一些问题
一 shiro的学习
官网和张开涛博客
二 shiro的java客户端配置
1.在web.xml中配置shiro的过滤器
- <!-- shiro 安全过滤器 -->
- <!-- The filter-name matches name of a 'shiroFilter' bean inside -->
- <filter>
- <filter-name>shiroFilter</filter-name>
- <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
- <async-supported>true</async-supported>
- <init-param>
- <param-name>targetFilterLifecycle</param-name>
- <param-value>true</param-value>
- </init-param>
- </filter>
- <filter-mapping>
- <filter-name>shiroFilter</filter-name>
- <url-pattern>/*</url-pattern>
- </filter-mapping>
<!-- shiro 安全过滤器 -->
<!-- The filter-name matches name of a 'shiroFilter' bean inside -->
<filter>
<filter-name>shiroFilter</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
<async-supported>true</async-supported>
<init-param>
<param-name>targetFilterLifecycle</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>shiroFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
同时在web.xml读取shiro的配置文件
2.在spring-shiro-web.xml中配置:
- <?xml version="1.0" encoding="UTF-8"?>
- <beans xmlns="http://www.springframework.org/schema/beans"
- xmlns:util="http://www.springframework.org/schema/util"
- 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.xsd
- http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.3.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd">
- <!-- 为了获取adminPath的值 -->
- <context:property-placeholder ignore-unresolvable="true" location="classpath*:/system.properties"/>
- <!-- 配置安全管理中心,Shiro的主要业务层对象基于web的应用程序 -->
- <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
- <property name="realm" ref="userRealm"/>
- </bean>
- <!-- 自定义的过滤器,用来验证登陆 -->
- <bean id="formAuthenticationCaptchaFilter" class="com.huaxia.shiro.FormAuthenticationCaptchaFilter">
- <property name="usernameParam" value="username"/>
- <property name="passwordParam" value="password"/>
- <property name="captchaParam" value="captcha"/>
- <property name="loginUrl" value="${adminPath}/login"/>
- </bean>
- <!-- 自定义的过滤器 -->
- <bean id="userFilter" class="com.huaxia.shiro.HuaXiaUserFilter">
- </bean>
- <!-- Shiro的Web过滤器,在web.xml中配置的shiroFilter即指向此 -->
- <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
- <!-- 指定一个安全管理中心,用来验证用户能否登陆和相关权限 -->
- <property name="securityManager" ref="securityManager"/>
- <!-- 所有地址被重定向到该地址 -->
- <property name="loginUrl" value="${adminPath}/login"/>
- <!-- 用户登录成功后的页面地址 -->
- <property name="successUrl" value="${adminPath}"/>
- <!-- 过滤器链,在shiroFilter之前即开始执行 -->
- <property name="filters">
- <util:map>
- <entry key="authc" value-ref="formAuthenticationCaptchaFilter"/>
- <entry key="user" value-ref="userFilter"/>
- </util:map>
- </property>
- <!-- 配置地址对应的过滤器 -->
- <property name="filterChainDefinitions">
- <value>
- ${adminPath}/login = authc
- /** = user
- </value>
- </property>
- </bean>
- <!-- 保证实现了Shiro内部lifecycle函数的bean执行 -->
- <bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor"/>
- <!-- 下面两个bean是shiro官网推荐的配置 -->
- <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>
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:util="http://www.springframework.org/schema/util"
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.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.3.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd">
<!-- 为了获取adminPath的值 -->
<context:property-placeholder ignore-unresolvable="true" location="classpath*:/system.properties"/>
<!-- 配置安全管理中心,Shiro的主要业务层对象基于web的应用程序 -->
<bean >
<property name="realm" ref="userRealm"/>
</bean>
<!-- 自定义的过滤器,用来验证登陆 -->
<bean >
<property name="usernameParam" value="username"/>
<property name="passwordParam" value="password"/>
<property name="captchaParam" value="captcha"/>
<property name="loginUrl" value="${adminPath}/login"/>
</bean>
<!-- 自定义的过滤器 -->
<bean >
</bean>
<!-- Shiro的Web过滤器,在web.xml中配置的shiroFilter即指向此 -->
<bean >
<!-- 指定一个安全管理中心,用来验证用户能否登陆和相关权限 -->
<property name="securityManager" ref="securityManager"/>
<!-- 所有地址被重定向到该地址 -->
<property name="loginUrl" value="${adminPath}/login"/>
<!-- 用户登录成功后的页面地址 -->
<property name="successUrl" value="${adminPath}"/>
<!-- 过滤器链,在shiroFilter之前即开始执行 -->
<property name="filters">
<util:map>
<entry key="authc" value-ref="formAuthenticationCaptchaFilter"/>
<entry key="user" value-ref="userFilter"/>
</util:map>
</property>
<!-- 配置地址对应的过滤器 -->
<property name="filterChainDefinitions">
<value>
${adminPath}/login = authc
/** = user
</value>
</property>
</bean>
<!-- 保证实现了Shiro内部lifecycle函数的bean执行 -->
<bean />
<!-- 下面两个bean是shiro官网推荐的配置 -->
<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>
其中UserRealm的实现如下:
- package com.huaxia.shiro;
- import javax.annotation.PostConstruct;
- import org.apache.shiro.SecurityUtils;
- import org.apache.shiro.authc.AuthenticationException;
- import org.apache.shiro.authc.AuthenticationInfo;
- import org.apache.shiro.authc.AuthenticationToken;
- import org.apache.shiro.authc.DisabledAccountException;
- import org.apache.shiro.authc.LockedAccountException;
- import org.apache.shiro.authc.SimpleAuthenticationInfo;
- import org.apache.shiro.authc.UnknownAccountException;
- import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
- 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.apache.shiro.util.ByteSource;
- import org.slf4j.Logger;
- import org.slf4j.LoggerFactory;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.stereotype.Service;
- import com.google.code.kaptcha.Constants;
- import com.huaxia.Constant;
- import com.huaxia.common.utils.security.Digests;
- import com.huaxia.common.utils.security.Encodes;
- import com.huaxia.user.entity.User;
- import com.huaxia.user.service.UserService;
- @Service
- public class UserRealm extends AuthorizingRealm {
- private Logger logger = LoggerFactory.getLogger(UserRealm.class);
- @Autowired
- private UserService userService;
- @Override
- protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
- String username = (String)principals.getPrimaryPrincipal();
- SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
- authorizationInfo.setRoles(userService.findRoles(username));
- authorizationInfo.setStringPermissions(userService.findPermissions(username));
- return authorizationInfo;
- }
- @Override
- protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
- UsernamePasswordCaptchaToken captchaToken = (UsernamePasswordCaptchaToken) token;
- String username = String.valueOf(token.getPrincipal());
- User user = userService.findByUsername(username,Constant.USER_DELFLAG);
- if(null != user && doCaptchValidate(captchaToken)) {
- if (Boolean.TRUE.equals(user.getLocked())) {
- throw new LockedAccountException(); //帐号锁定
- }
- if(Constant.LOGIN_STATUS_N.equals(user.getLoginStatus())){
- throw new DisabledAccountException();
- }
- byte[] salt = Encodes.decodeHex(user.getSalt());
- //交给AuthenticatingRealm使用CredentialsMatcher进行密码匹配,可以自定义实现
- SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(
- user.getUserName(),
- user.getPassword(), //密码
- ByteSource.Util.bytes(salt),
- getName() //realm name
- );
- //SecurityUtils.getSubject().getSession().setAttribute("user", user);
- SecurityUtils.getSubject().getSession().setAttribute("userId", user.getUserId());
- userService.updateByLogin(user);
- return authenticationInfo;
- }else{
- throw new UnknownAccountException();
- }
- }
- protected boolean doCaptchValidate(UsernamePasswordCaptchaToken token){
- String captcha = (String) SecurityUtils.getSubject().getSession().getAttribute(Constants.KAPTCHA_SESSION_KEY);
- if(captcha != null && !captcha.equalsIgnoreCase(token.getCaptcha())){
- throw new CaptchaException("Code error");
- }
- return true;
- }
- @PostConstruct
- public void initCredentialsMatcher() {
- HashedCredentialsMatcher matcher = new HashedCredentialsMatcher(Digests.SHA1);
- matcher.setHashIterations(Constant.HASH_INTERATIONS);
- setCredentialsMatcher(matcher);
- }
- @Override
- public void clearCachedAuthorizationInfo(PrincipalCollection principals) {
- super.clearCachedAuthorizationInfo(principals);
- }
- @Override
- public void clearCachedAuthenticationInfo(PrincipalCollection principals) {
- super.clearCachedAuthenticationInfo(principals);
- }
- @Override
- public void clearCache(PrincipalCollection principals) {
- super.clearCache(principals);
- }
- public void clearAllCachedAuthorizationInfo() {
- getAuthorizationCache().clear();
- }
- public void clearAllCachedAuthenticationInfo() {
- getAuthenticationCache().clear();
- }
- public void clearAllCache() {
- clearAllCachedAuthenticationInfo();
- clearAllCachedAuthorizationInfo();
- }
- }
package com.huaxia.shiro;
import javax.annotation.PostConstruct;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.DisabledAccountException;
import org.apache.shiro.authc.LockedAccountException;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
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.apache.shiro.util.ByteSource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.google.code.kaptcha.Constants;
import com.huaxia.Constant;
import com.huaxia.common.utils.security.Digests;
import com.huaxia.common.utils.security.Encodes;
import com.huaxia.user.entity.User;
import com.huaxia.user.service.UserService;
@Service
public class UserRealm extends AuthorizingRealm {
private Logger logger = LoggerFactory.getLogger(UserRealm.class);
@Autowired
private UserService userService;
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
String username = (String)principals.getPrimaryPrincipal();
SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
authorizationInfo.setRoles(userService.findRoles(username));
authorizationInfo.setStringPermissions(userService.findPermissions(username));
return authorizationInfo;
}
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
UsernamePasswordCaptchaToken captchaToken = (UsernamePasswordCaptchaToken) token;
String username = String.valueOf(token.getPrincipal());
User user = userService.findByUsername(username,Constant.USER_DELFLAG);
if(null != user && doCaptchValidate(captchaToken)) {
if (Boolean.TRUE.equals(user.getLocked())) {
throw new LockedAccountException(); //帐号锁定
}
if(Constant.LOGIN_STATUS_N.equals(user.getLoginStatus())){
throw new DisabledAccountException();
}
byte[] salt = Encodes.decodeHex(user.getSalt());
//交给AuthenticatingRealm使用CredentialsMatcher进行密码匹配,可以自定义实现
SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(
user.getUserName(),
user.getPassword(), //密码
ByteSource.Util.bytes(salt),
getName() //realm name
);
//SecurityUtils.getSubject().getSession().setAttribute("user", user);
SecurityUtils.getSubject().getSession().setAttribute("userId", user.getUserId());
userService.updateByLogin(user);
return authenticationInfo;
}else{
throw new UnknownAccountException();
}
}
protected boolean doCaptchValidate(UsernamePasswordCaptchaToken token){
String captcha = (String) SecurityUtils.getSubject().getSession().getAttribute(Constants.KAPTCHA_SESSION_KEY);
if(captcha != null && !captcha.equalsIgnoreCase(token.getCaptcha())){
throw new CaptchaException("Code error");
}
return true;
}
@PostConstruct
public void initCredentialsMatcher() {
HashedCredentialsMatcher matcher = new HashedCredentialsMatcher(Digests.SHA1);
matcher.setHashIterations(Constant.HASH_INTERATIONS);
setCredentialsMatcher(matcher);
}
@Override
public void clearCachedAuthorizationInfo(PrincipalCollection principals) {
super.clearCachedAuthorizationInfo(principals);
}
@Override
public void clearCachedAuthenticationInfo(PrincipalCollection principals) {
super.clearCachedAuthenticationInfo(principals);
}
@Override
public void clearCache(PrincipalCollection principals) {
super.clearCache(principals);
}
public void clearAllCachedAuthorizationInfo() {
getAuthorizationCache().clear();
}
public void clearAllCachedAuthenticationInfo() {
getAuthenticationCache().clear();
}
public void clearAllCache() {
clearAllCachedAuthenticationInfo();
clearAllCachedAuthorizationInfo();
}
}
其中formAuthenticationCaptchaFilter的实现如下:
- package com.huaxia.shiro;
- import javax.servlet.ServletRequest;
- import javax.servlet.ServletResponse;
- import javax.servlet.http.HttpServletRequest;
- import javax.servlet.http.HttpServletResponse;
- import org.apache.shiro.authc.AuthenticationToken;
- import org.apache.shiro.subject.Subject;
- import org.apache.shiro.web.filter.authc.FormAuthenticationFilter;
- import org.apache.shiro.web.util.WebUtils;
- import org.slf4j.Logger;
- import org.slf4j.LoggerFactory;
- public class FormAuthenticationCaptchaFilter extends FormAuthenticationFilter {
- private Logger logger = LoggerFactory.getLogger(FormAuthenticationCaptchaFilter.class);
- public static final String DEFAULT_CAPTCHA_PARAM = "captcha";
- private String captchaParam = DEFAULT_CAPTCHA_PARAM;
- public String getCaptchaParam() {
- return captchaParam;
- }
- public void setCaptchaParam(String captchaParam){
- this.captchaParam = captchaParam;
- }
- protected String getCaptcha(ServletRequest request) {
- return WebUtils.getCleanParam(request, getCaptchaParam());
- }
- protected AuthenticationToken createToken(ServletRequest request, ServletResponse response) {
- String username = getUsername(request) == null ? "" : getUsername(request);
- String password = getPassword(request) == null ? "" : getPassword(request);
- String captcha = getCaptcha(request) == null ? "" : getCaptcha(request);
- boolean rememberMe = isRememberMe(request);
- return new UsernamePasswordCaptchaToken(username,password.toCharArray(), rememberMe, captcha);
- }
- @Override
- protected boolean onLoginSuccess(AuthenticationToken token, Subject subject,
- ServletRequest request, ServletResponse response) throws Exception {
- // issueSuccessRedirect(request, response);
- // we handled the success redirect directly, prevent the chain from continuing:
- HttpServletRequest httpServletRequest = (HttpServletRequest)request;
- HttpServletResponse httpServletResponse = (HttpServletResponse)response;
- if (!"XMLHttpRequest".equalsIgnoreCase(httpServletRequest.getHeader("X-Requested-With"))
- || request.getParameter("ajax") == null) {// 不是ajax请求
- httpServletResponse.sendRedirect(httpServletRequest.getContextPath() + this.getSuccessUrl());
- } else {
- httpServletResponse.sendRedirect(httpServletRequest.getContextPath() + this.getSuccessUrl());
- }
- return false;
- }
- }
package com.huaxia.shiro;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.web.filter.authc.FormAuthenticationFilter;
import org.apache.shiro.web.util.WebUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class FormAuthenticationCaptchaFilter extends FormAuthenticationFilter {
private Logger logger = LoggerFactory.getLogger(FormAuthenticationCaptchaFilter.class);
public static final String DEFAULT_CAPTCHA_PARAM = "captcha";
private String captchaParam = DEFAULT_CAPTCHA_PARAM;
public String getCaptchaParam() {
return captchaParam;
}
public void setCaptchaParam(String captchaParam){
this.captchaParam = captchaParam;
}
protected String getCaptcha(ServletRequest request) {
return WebUtils.getCleanParam(request, getCaptchaParam());
}
protected AuthenticationToken createToken(ServletRequest request, ServletResponse response) {
String username = getUsername(request) == null ? "" : getUsername(request);
String password = getPassword(request) == null ? "" : getPassword(request);
String captcha = getCaptcha(request) == null ? "" : getCaptcha(request);
boolean rememberMe = isRememberMe(request);
return new UsernamePasswordCaptchaToken(username,password.toCharArray(), rememberMe, captcha);
}
@Override
protected boolean onLoginSuccess(AuthenticationToken token, Subject subject,
ServletRequest request, ServletResponse response) throws Exception {
// issueSuccessRedirect(request, response);
// we handled the success redirect directly, prevent the chain from continuing:
HttpServletRequest httpServletRequest = (HttpServletRequest)request;
HttpServletResponse httpServletResponse = (HttpServletResponse)response;
if (!"XMLHttpRequest".equalsIgnoreCase(httpServletRequest.getHeader("X-Requested-With"))
|| request.getParameter("ajax") == null) {// 不是ajax请求
httpServletResponse.sendRedirect(httpServletRequest.getContextPath() + this.getSuccessUrl());
} else {
httpServletResponse.sendRedirect(httpServletRequest.getContextPath() + this.getSuccessUrl());
}
return false;
}
}
其中HuaXiaUserFilter的实现如下:
- package com.huaxia.shiro;
- import org.apache.shiro.web.filter.authc.UserFilter;
- import org.apache.shiro.web.filter.session.NoSessionCreationFilter;
- import org.apache.shiro.web.util.WebUtils;
- import javax.servlet.ServletRequest;
- import javax.servlet.ServletResponse;
- import javax.servlet.http.HttpServletResponse;
- public class HuaXiaUserFilter extends UserFilter {
- @Override
- protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception {
- /*if(!"XMLHttpRequest".equalsIgnoreCase(WebUtils.toHttp(response).getHeader("X-Requested-With"))
- || request.getParameter("ajax") == null ){
- this.saveRequestAndRedirectToLogin(request, response);
- }else{*/
- HttpServletResponse res = WebUtils.toHttp(response);
- res.setHeader("sessionstatus","timeout");
- //res.sendError(HttpServletResponse.SC_UNAUTHORIZED);
- /* }*/
- this.saveRequestAndRedirectToLogin(request, response);
- return false;
- }
- }
package com.huaxia.shiro;
import org.apache.shiro.web.filter.authc.UserFilter;
import org.apache.shiro.web.filter.session.NoSessionCreationFilter;
import org.apache.shiro.web.util.WebUtils;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletResponse;
public class HuaXiaUserFilter extends UserFilter {
@Override
protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception {
/*if(!"XMLHttpRequest".equalsIgnoreCase(WebUtils.toHttp(response).getHeader("X-Requested-With"))
|| request.getParameter("ajax") == null ){
this.saveRequestAndRedirectToLogin(request, response);
}else{*/
HttpServletResponse res = WebUtils.toHttp(response);
res.setHeader("sessionstatus","timeout");
//res.sendError(HttpServletResponse.SC_UNAUTHORIZED);
/* }*/
this.saveRequestAndRedirectToLogin(request, response);
return false;
}
}
3.另外在Mvc的配置文件spring-mvc.xml中加入如下拦截器内容:- <aop:config proxy-target-class="true"></aop:config>
- <bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">
- <property name="securityManager" ref="securityManager"/>
- </bean>
<aop:config proxy-target-class="true"></aop:config>
<bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">
<property name="securityManager" ref="securityManager"/>
</bean>
三 关于权限的一些问题
1.shiro如何实现验证码?
关于shiro的验证码,使用的是google的kaptcha , 在web.xml中配置sevlet如下:
- <servlet>
- <servlet-name>ImageServlet</servlet-name>
- <servlet-class>com.google.code.kaptcha.servlet.KaptchaServlet</servlet-class>
- </servlet>
- <servlet-mapping>
- <servlet-name>ImageServlet</servlet-name>
- <url-pattern>/ImageServlet</url-pattern>
- </servlet-mapping>
<servlet>
<servlet-name>ImageServlet</servlet-name>
<servlet-class>com.google.code.kaptcha.servlet.KaptchaServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>ImageServlet</servlet-name>
<url-pattern>/ImageServlet</url-pattern>
</servlet-mapping></pre>
2.用户名密码通常保存为什么要加盐值?
由于通常密码保存使用的是md5加密,同样的密码在md5后会产生相同的加密后字符串,如果有数据库的查看权限,那么看到相同的加密后字符串,很容易猜到是相同的密码。同时根据md5对照表(或者一些网站),能够找到密码。 如果密码在加上随机盐后再进行md5,那么同样的密码在md5后的字符串是不同的,就能够避免上面两个问题。总的来说增加了破解的难度。
3.通常情况下用户-角色-权限(资源)之间的关系
用户与角色多对多:一个用户可以拥有多个角色,一个角色可以被多个用户具有
角色与权限(资源,主要指菜单,按钮等)多对多:一个角色可以拥有多个权限,一个权限可以被多个角色拥有
3.1 在首页,通常根据用户查找角色,然后根据角色列出相关的菜单栏和相关按钮
3.2 在系统配置中:
用户配置:可以增删用户,也可以配置用户的多个角色
角色配置:可以配置一个角色的多个权限
权限配置:可以增删相关的资源(菜单或者按钮)
4.shiro授权的几种方式:
4.1 在代码体中:
[java] view plain copy
- if (currentUser.hasRole("admin"))
if (currentUser.hasRole("admin"))
4.2 在方法上:
[java] view plain copy
- @RequiresPermissions(“account:create”)
- public void openAccount( Account acct )
@RequiresPermissions(“account:create”)
public void openAccount( Account acct )
4.3 在jsp页面上:
[java] view plain copy
- <shiro:hasPermission name=“users:manage”>
- <a href=“manageUsers.jsp”> </a>
- </shiro:hasPermission>
<shiro:hasPermission name=“users:manage”>
<a href=“manageUsers.jsp”> </a>
</shiro:hasPermission>
Shiro的官方文档整理的感觉差强人意,非常不明朗,需要结合张开涛的博客来看。有很多的地方需要学习,后续更新。
相关推荐
-
用grunt搭建自动化的web前端开发环境-完整教程
1. 前言
2. 安装nodejs
3. 安装grunt-CLI
4. 创建一个简单的网站
5. 安装grunt
6. 配置Gruntfile.js
7. Grunt插件介绍
8. 使用uglify插件(压缩javascript代码)
9. 使用jshint插件(检查javascript语法错误)
10. 使用csslint插件(检查css语法错误)
11. 使用watch插件(真正实现自动化)
12. 上文中所谓的“build”
13. 批量安装插件
14. 系统文件结构
15. 完结
-
复制自己的web项目时应该注意
-
vue-cli3构建的项目打包部署在非根目录下的服务器时需要进行的配置
-
ubuntu下的nginx+php+mysql安装配置(转)
-
springboot结合shiro的配置类
-
【转】Fragment对用户可见的判断实践,亲测有效
概述
先说说几个重要的函数
说说我项目中的封装
总结
-
Keepalived+Nginx+Tomcat 实现高可用Web集群(转)
Keepalived+Nginx+Tomcat 实现高可用Web集群
一、Nginx的安装过程
二、KeepAlived安装和配置
三、集群规划和搭建
四、Keepalived抢占模式和非抢占模式
-
【idea中创建springMVC项目的2个坑】不识别@Autowired 以及 Mapper.xml的配置
-
最近总是找springboot 的配置文件。不想每次创建新项目都找,所以记录一下。
-
Intellij IDEA 常用设置
转:请叫我小思
显示工具条
设置鼠标悬浮提示
显示方法分隔符
忽略大小写提示
主题设置
护眼主题设置
自动导入包
单行显示多个Tabs
设置字体
配置类文档注释信息和方法注释模版
水平或者垂直显示代码
更换快捷键
注释去掉斜体
代码检测警告提示等级设置
项目目录相关–折叠空包
窗口复位
查看本地代码历史
快速补全分号
快速找到Controller方法
大括号匹配
-
jQuery常用方法(持续更新) jQuery(转)
0、常用代码:
1、关于页面元素的引用
2、jQuery对象与dom对象的转换
3、如何获取jQuery集合的某一项
4、同一函数实现set和get
5、集合处理功能
6、扩展我们需要的功能
7、支持方法的连写
8、操作元素的样式
9、完善的事件处理功能
10、几个实用特效功能
11、几个有用的jQuery方法
12、解决自定义方法或其他类库与jQuery的冲突
13、jQuery实现回车监听
-
代码生成空白页面