Shiro与基于spring项目的整合 (shiro 第六篇)

本文介绍如何将Apache Shiro安全框架整合到基于Spring的Web应用中,包括配置Web.xml和Application.xml文件,实现自定义的认证过滤器和授权过滤器,并通过MyRealm进行用户身份验证和权限检查。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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;    
    }

}

 

完.

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值