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 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>
其中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 在代码体中:
- if (currentUser.hasRole("admin"))
if (currentUser.hasRole("admin"))4.2 在方法上:
- @RequiresPermissions(“account:create”)
- public void openAccount( Account acct )
@RequiresPermissions(“account:create”)
public void openAccount( Account acct )4.3 在jsp页面上:
- <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的官方文档整理的感觉差强人意,非常不明朗,需要结合张开涛的博客来看。有很多的地方需要学习,后续更新。
Shiro的Web项目配置(转)的更多相关文章
- Intellij IDEA创建的Web项目配置Tomcat并启动Maven项目
本篇博客讲解IDEA如何配置Tomcat. 大部分是直接上图哦. 点击如图所示的地方,进行添加Tomcat配置页面 弹出页面后,按照如图顺序找到,点击+号 tomcat Service -> L ...
- Tomcat 中如何给 web 项目配置虚拟目录的方法
为什么要给 web 项目配置虚拟目录? 初学 JavaWeb 时,会发现只要我们把 web 项目放到 Tomcat 的 webapps 目录下,再通过 http://localhost:8080/项目 ...
- 给本地web项目配置域名
给本地的web项目配置一个域名 通常访问本地问项目时,使用localhost:port/projectname或者127.0.0.1:port/projectname来实现.我们可以通过配置tomca ...
- Java Web项目 配置 ueditor心得
近期的JAVA项目,由于客户要求需要引入富文本编辑器. 参考了两款插件,一款是ckeditor,一款是ueditor. ckeditor在上传文件的时候必须配合ckfinder使用,而ckfinder ...
- web项目配置webAppRootKey 获得根目录 .
log4j和web.xml配置webAppRootKey 的问题 1 在web.xml配置 <context-param> <param-name>webAppRootKey ...
- 【IDEA】Intellij IDEA创建的Web项目配置Tomcat并启动Maven项目
转载请注明出处:http://blog.csdn.net/qq_26525215本文源自[大学之旅_谙忆的博客] 本篇博客讲解IDEA如何配置Tomcat. 大部分是直接上图哦. 点击如图所示的地方, ...
- idea 普通 web项目配置启动【我】
首先说这是一个普通的java web项目,没有用到maven. 检出项目: 项目是先用 乌龟svn 在 编辑器外部检出到一个目录下,然后再用 idea的 open 打开这个目录生成的.[因为直接用i ...
- shiro与Web项目整合-Spring+SpringMVC+Mybatis+Shiro(八)
Jar包
- IDEA创建的Web项目配置Tomcat并启动Maven项目
点击如图所示的地方,进行添加Tomcat配置页面 弹出页面后,按照如图顺序找到,点击+号 tomcat Service -> Local 注意,这里不要选错了哦,还有一个TomE ...
随机推荐
- BZOJ 1232 Kruskal
思路: 跟昨天的考试题特别像-.. 就是裸的Kruskal 把边权设为连接的两个点的点权之和加上边权*2 搞定 //By SiriusRen #include <cstdio> #incl ...
- javafx progressbar
import javafx.application.Application; import javafx.beans.value.ChangeListener; import javafx.beans ...
- cat---查看文件内容
- ZJU 2425 Inversion
Inversion Time Limit: 2000ms Memory Limit: 65536KB This problem will be judged on ZJU. Original ID: ...
- 设计模式(7)-结构型模式-Bridge模式
2.结构性模式 2.2 BRIDGE模式 别名:handle/body 这个模式体现了组合相对于继承的优势. 2.2.1动机 当一个抽象可能有多个实现时,通经常使用继承来协调它们.抽象类定义对该抽象 ...
- Makefile 文件格式
Makefile包含 目标文件.依赖文件.可运行命令三部分. 每部分的基本格式例如以下: test: prog.o code.o gcc -o test prog.o code.o 当中 ...
- 4个开源的Gmail替代品
资料来源 https://opensource.com/alternatives/gmail 本文是对原文翻译,在调试 privmx 时么有成功,这些代码大多用于 php5 ,对PHP7 不兼容. 相 ...
- Android学习笔记进阶19之给图片加边框
//设置颜色 public void setColour(int color){ co = color; } //设置边框宽度 public void setBorderWidth(int width ...
- unity-unet-同步各个player唯一标识
Multiplayer Game 中所有 player 都有一个唯一标识.在unet中可以通过 Network Identity 组件获取到该 player 在整个网络整的 唯一 的连接 id 这里测 ...
- 洛谷 P2562 [AHOI2002]Kitty猫基因编码
P2562 [AHOI2002]Kitty猫基因编码 题目描述 小可可选修了基础生物基因学.教授告诉大家 Super Samuel 星球上 Kitty猫的基因的长度都是 2 的正整数次幂 ), 全是由 ...