SHIRO
第一步# 首先在Maven的pom.xml引入shiro两个库
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-core</artifactId>
<version>1.3.2</version>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>1.3.2</version>
</dependency>
第二步# 在web.xml中配置shiro的过滤器,这个过滤器需要配置在所有过滤器上方
<!-- shiro filter -->
<filter>
<filter-name>shiroFilter</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
<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>
第三步# 在applicationContext中配置shiro子过滤器以实现认证 授权等功能
<!-- shiro 核心配置 -->
<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
<property name="securityManager" ref="securityManager"/>
<property name="filters">
<map>
<entry key="statelessAuthc" value-ref="authFilter"/>
</map>
</property>
<!-- 无权限路径 -->
<property name="unauthorizedUrl" value="/403"/>
<property name="filterChainDefinitions">
<value>
/admin/** = authc, roles[admin]
/docs/** = authc, perms[document:read]
/shiro/get/**=statelessAuthc, roles[admins]
<!--/** = authc-->
</value>
</property>
</bean>
<!-- SecurityManager -->
<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
<property name="realm" ref="myRealm"/>
<!-- 禁用主体状态保存到session中 -->
<property name="securityManager.subjectDAO.sessionStorageEvaluator.sessionStorageEnabled " value="false" />
<property name="sessionManager" ref="sessionManager"/>
</bean>
<!-- 会话管理 -->
<bean id="sessionManager" class="org.apache.shiro.web.session.mgt.DefaultWebSessionManager" >
<!-- 禁用session cookie -->
<property name="SessionIdCookieEnabled" value="false"></property>
<property name="sessionValidationSchedulerEnabled" value="false"></property>
</bean>
<!-- 数据视图 -->
<bean id="myRealm" class="com.zhiyeit.shiro.MyRealm" />
<bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor"/>
第四步#
实现authFilter
package com.zhiyeit.shiro; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.shiro.authc.UsernamePasswordToken; import org.apache.shiro.web.filter.AccessControlFilter; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.http.HttpStatus; import org.springframework.web.bind.annotation.RequestMethod; /** * 验证用户的真实性 认证过滤器 * @author public * */ public class AuthFilter extends AccessControlFilter { final static Logger log = LoggerFactory.getLogger(AuthFilter.class); @Override protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) throws Exception {//如果返回true 则不走下面的检测用户有效性的方法 return false; } @Override protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception { HttpServletRequest httpServletRequest=(HttpServletRequest)request; HttpServletResponse httpServletResponse=(HttpServletResponse)response; String token=httpServletRequest.getHeader("access-token"); UsernamePasswordToken usertoken=new UsernamePasswordToken(token,token); try{
//shiro 验证用户是否已经登陆 getSubject(request, response).login(usertoken); }catch (Exception e) { log.info("token过期或没登录的用户"); HttpServletResponse rs=(HttpServletResponse)response; rs.setStatus(HttpStatus.UNAUTHORIZED.value()); return false; } //验证通过 可以访问资源
return true; } }
实现myrealm
package com.zhiyeit.shiro; import java.util.HashSet; import java.util.List; import java.util.Set; import org.apache.shiro.authc.AuthenticationException; import org.apache.shiro.authc.AuthenticationInfo; import org.apache.shiro.authc.AuthenticationToken; import org.apache.shiro.authc.IncorrectCredentialsException; import org.apache.shiro.authc.SimpleAuthenticationInfo; import org.apache.shiro.authc.UsernamePasswordToken; 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.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.redis.core.RedisTemplate; import com.zhiyeit.util.Tool; public class MyRealm extends AuthorizingRealm { final static Logger log = LoggerFactory.getLogger(AuthFilter.class); @Autowired RedisTemplate<String,Object> redisTemplate; @Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) { String username = (String) principals.getPrimaryPrincipal(); SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo(); Set<String> role_set=new HashSet<String>(); List<Object> role_list=this.redisTemplate.boundListOps(username).range(0, -1); role_list.forEach(role_string->{ role_set.add((String)role_string); }); authorizationInfo.setRoles(role_set); return authorizationInfo; } @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException { UsernamePasswordToken usertoken=(UsernamePasswordToken) token; String user=usertoken.getUsername(); if(Tool.notBlank(user)&&redisTemplate.getExpire(user)>1){ return new SimpleAuthenticationInfo(user,user,user); }else{ throw new IncorrectCredentialsException(); } } }