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>
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>
其中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.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 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;
- }
- }
- <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>