SHIRO
下面是shiro整合基于spring的web项目
Web.xml
除了你的spring web.xml 元素(ContextLoaderListener,Log4jConfigListener),定义下面的过滤器和过滤器Mapping:
<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-mapping之前,以保证子过滤器在过滤器链中正常工作-->
<filter-mapping>
<filter-name>shiroFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
Application.xml
<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
<property name="realm" ref="myRealm"/>
</bean>
<!-- 验证用户的过滤器 -->
<bean id="authFilter" class="com.company_name.AuthFilter" />
<bean id="roleFilter" class="com.company_name.RoleFilter"></bean>
<!--Realm-->
<bean id="myRealm" class="com.company_name.MyRealm" />
<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"/>
<entry key="costumrole" value-ref="roleFilter" />
</map>
</property>
<!-- 无权限路径 -->
<property name="unauthorizedUrl" value="/403"/>
<property name="filterChainDefinitions">
<value>
<!--路径配置-->
/admin/login=anon
<!--请求被分配到statelessAuthc,costumrole这两个过滤器中-->
/admin/** = statelessAuthc,costumrole[publishrole,systemadmin]
</value>
</property>
</bean>
MyReal.java
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.springframework.beans.factory.annotation.Autowired;
public class MyRealm extends AuthorizingRealm {
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
String username = (String) principals.getPrimaryPrincipal();
SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
Set<String> role_set=new HashSet<String>();
<!--假设有这两个权限 后续要从数据库中使用username 取出来权限放到这里-->
<!---与applicationContex.xml中costumrole[publishrole,systemadmin]对应-->
role_set.add("publishrole");
role_set.add("systemadmin");
authorizationInfo.setRoles(role_set);
return authorizationInfo;
}
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
UsernamePasswordToken usertoken=(UsernamePasswordToken) token;
String user=usertoken.getUsername();
char[] pass=usertoken.getPassword();
if("验证用户状态有效性 如果有效返回下面的SimpleAuthenticationInfo 否则返回异常"){
return new SimpleAuthenticationInfo(user,user,user);
}else{
throw new IncorrectCredentialsException();
}
}
}
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 {
/**
* 当返回值为false时才走验证函数
*/
@Override
protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue)
throws Exception {
return false;
}
@Override
protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception {
HttpServletRequest httpServletRequest=(HttpServletRequest)request;
HttpServletResponse httpServletResponse=(HttpServletResponse)response;
String username=httpServletRequest.getHeader("username");
String pass=httpServletRequest.getHeader("pass");
if(httpServletRequest.getMethod().equals(RequestMethod.OPTIONS.name())){
httpServletResponse.setStatus(HttpStatus.OK.value());
return false;
}
UsernamePasswordToken usertoken=new UsernamePasswordToken(username,pass);
try{
<!--这个方法调用 MyRealm.java 的AuthenticationInfo方法验证用户有效性-->
getSubject(request, response).login(usertoken);
}catch (Exception e) {
log.info("token过期或没登录的用户");
HttpServletResponse rs=(HttpServletResponse)response;
rs.setStatus(HttpStatus.UNAUTHORIZED.value());
return false;
}
return true;
}
}
RoleFilter.java
package com.zhiyeit.shiro;
import java.io.IOException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.web.filter.authz.AuthorizationFilter;
/**
* 授权验证 角色过滤器
* @author public
*
*/
public class RoleFilter extends AuthorizationFilter {
//TODO - complete JavaDoc
public boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) throws IOException {
Subject subject = getSubject(request, response);
<!--mappedValue与MyRealm的doGetAuthorizationInfo对应-->
String[] rolesArray = (String[]) mappedValue;
if (rolesArray == null || rolesArray.length == 0) {
//no roles specified, so nothing to check - allow access.
return true;
}
for (int i = 0; i < rolesArray.length; i++) {
if (subject.hasRole(rolesArray[i])) { //若当前用户是rolesArray中的任何一个,则有权限访问
return true;
}
}
return false;
}
}
完.