shiro简单使用

shiro配置文件shiro.xml,主要是暴露几个自定义的类

1、跟当前用户有关系的类,MyRealm.java,登陆验证,当前用户具有的角色权限

2、跟项目所有权限有关的类,ChainDefinitionSectionMetaSource.java,加载所有的权限,启动项目的时候加载

3、自定义验证功能的类,MyPermissionAuthorizationFilter.java,这个是权限自定义验证的类,比如一条路径有多个权限,自定义这些权限是或的关系还是并的关系。比如一个因为权限不足而被阻挡的访问,判断是普通浏览器请求还是ajax请求,根据不同请求给出不同的响应。

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       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/context
          http://www.springframework.org/schema/context/spring-context.xsd">


    <context:component-scan base-package="shiro"/>

    <bean id="myRealm" class="shiro.MyRealm"/>

    <!-- 配置SecurityManager的管理 -->
    <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
        <!-- 配置需要使用的Realms -->
        <property name="realm" ref="myRealm"/>
    </bean>

    <!-- 配置shiro过滤器 -->
    <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
        <!-- 配置一个安全管理器 -->
        <property name="securityManager" ref="securityManager"/>
        <!-- 出现错误之后的跳转路径配置 -->
        <property name="loginUrl" value="/user/login"/>
        <!-- 认证失败之后的跳转路径页面 -->
        <property name="unauthorizedUrl" value="/user/message"/>
        <!-- 自定义验证规则 -->
        <property name="filters">
            <map>
                <entry key="perms">
                    <bean
                            class="shiro.MyPermissionAuthorizationFilter" />
                </entry>
                <!--退出过滤器-->
                <entry key="logout" value-ref="logoutFilter" />
            </map>
        </property>

        <!-- 自定义一个类,动态为路径添加角色权限等信息 -->
        <property name="filterChainDefinitionMap" ref="chainDefinitionSectionMetaSource" />
    </bean>
    <!--自定义LogoutFilter,退出-->
    <bean id="logoutFilter" class="org.apache.shiro.web.filter.authc.LogoutFilter">
        <property name="redirectUrl" value="/user/login"/>
    </bean>

    <bean id="chainDefinitionSectionMetaSource" class="shiro.ChainDefinitionSectionMetaSource">

        <property name="filterChainDefinitions">
            <value>
                /manage/enduser/query=authc,perms[perm1]
                /=authc
                /manage/enduser/logout=logout
            </value>
        </property>
    </bean>

</beans>

记得将shiro.xml路径加到中,filter要使用shiroFilter,都是修改web.xml

<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xmlns="http://java.sun.com/xml/ns/javaee"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
              http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
         version="3.0">

    <servlet>
        <servlet-name>springmvc</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:springmvc-servlet.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>springmvc</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>


    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>
            classpath:applicationContext.xml
            classpath:shiro.xml
        </param-value>
    </context-param>
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

    <filter>
        <filter-name>CharacterEncodingFilter</filter-name>
        <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
        <init-param>
            <param-name>encoding</param-name>
            <param-value>utf-8</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>CharacterEncodingFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

    <!-- shiroFilter : DelegatingFilterProxy作用是自动到spring容器查找名字为shiroFilter(filter-name)的bean并把所有Filter的操作委托给它。然后将shiroFilter配置到spring容器即可 -->
    <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>
</web-app>

自定义的几个类

MyRealm.java

package shiro;

import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
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.stereotype.Component;

import java.util.HashSet;
import java.util.Set;

/**
 * @ClassName MyRealm
 * @Description TODO
 * @Author shuai
 * @Date 2018/6/11 17:07
 * @Version 1.0
 **/
@Component
public class MyRealm extends AuthorizingRealm {

	public MyRealm() {
		System.out.println("MyRealm扫描到了!!!");
	}

	@Override
	protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
		//获取传过来的用户名
		String username = (String) token.getPrincipal();
		//获取传过来的密码
		String password = new String((char[]) token.getCredentials());

		//判断该用户是否存在...

		return new SimpleAuthenticationInfo(username, password, "testRealm");

	}

	@Override
	protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
		//此时说明用户已经登录成功了(上面方法验证成功后才会进入此方法),此方法用来加载用户的角色和权限
		//用来携带角色,权限
		SimpleAuthorizationInfo auth = new SimpleAuthorizationInfo();
		//存角色
		Set<String> roles = new HashSet<>();
		//存权限
		Set<String> stringPermissions = new HashSet<>();
		//获取当前登录用户的用户名
		String username = (String) principalCollection.getPrimaryPrincipal();
		//获取用户...
		System.out.println("当前用户具有的权限");
		stringPermissions.add("hello");
		//目前只设置权限,暂时不管角色
		//auth.setRoles(roles);
		auth.setStringPermissions(stringPermissions);
		return auth;
	}
}

ChainDefinitionSectionMetaSource.java

package shiro;

import org.apache.shiro.config.Ini;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.stereotype.Component;

import java.text.MessageFormat;

/**
 * @ClassName ChainDefinitionSectionMetaSource
 * @Description TODO
 * @Author shuai
 * @Date 2018/6/11 17:07
 * @Version 1.0
 **/
@Component
public class ChainDefinitionSectionMetaSource implements FactoryBean<Ini.Section> {

	private String filterChainDefinitions;


	/**
	 * 设置权限格式,与配置文件中自定义的key一致
	 */
	public static final String PREMISSION_STRING = "perms[\"{0}\"]";

	public ChainDefinitionSectionMetaSource() {
		System.out.println("ChainDefinitionSectionMetaSource扫描到了!!!");
	}

	public ChainDefinitionSectionMetaSource(String filterChainDefinitions) {
		this.filterChainDefinitions = filterChainDefinitions;
	}


	@Override
	public Ini.Section getObject() {
		Ini ini = new Ini();
		//加载默认的url
		ini.load(filterChainDefinitions);
		Ini.Section section = ini.getSection(Ini.DEFAULT_SECTION_NAME);

		//加载所有权限...

		//循环Resource的url,逐个添加到section中。section就是filterChainDefinitionMap
		//里面的键就是链接URL,值就是存在什么条件才能访问该链接
		putDefinitionSection(section, "/hello", "hello");
        putDefinitionSection(section, "/hello1", "hello1");
		return section;
	}

	private void putDefinitionSection(Ini.Section section, String key, String value) {
		System.out.println("加载数据库权限:【key=" + key + "\tvalue=" + value + "】");
		section.put(key, MessageFormat.format(PREMISSION_STRING, value));
	}

	public void setFilterChainDefinitions(String filterChainDefinitions) {
		this.filterChainDefinitions = filterChainDefinitions;
	}

	@Override
	public Class<?> getObjectType() {
		return this.getClass();
	}

	@Override
	public boolean isSingleton() {
		return false;
	}
}

MyPermissionAuthorizationFilter.java

package shiro;

import org.apache.shiro.subject.Subject;
import org.apache.shiro.util.CollectionUtils;
import org.apache.shiro.util.StringUtils;
import org.apache.shiro.web.filter.authz.AuthorizationFilter;
import org.apache.shiro.web.util.WebUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Set;

/**
 * @ClassName MyPermissionAuthorizationFilter
 * @Description TODO
 * @Author shuai
 * @Date 2018/6/11 17:07
 * @Version 1.0
 **/
@Component
public class MyPermissionAuthorizationFilter extends AuthorizationFilter {

	private static Logger log = LoggerFactory.getLogger(MyPermissionAuthorizationFilter.class);

	@Override
	protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws IOException {

		final String AJAX_SIGN = "XMLHttpRequest";

		//验证是否为ajax请求时用到
		HttpServletRequest httpServletRequest = (HttpServletRequest) request;
		//ajax请求返回值时用到
		HttpServletResponse httpServletResponse = (HttpServletResponse) response;
		//值为XMLHttpRequest表示ajax请求
		String requestType = httpServletRequest.getHeader("X-Requested-With");
		Subject subject = getSubject(request, response);
		//判断是否登录成功
		//未登录
		if (subject.getPrincipal() == null) {
			if (AJAX_SIGN.equals(requestType)) {
				log.info("未登录ajax请求");
				httpServletResponse.setCharacterEncoding("UTF-8");
				httpServletResponse.getWriter().write("请登录");
			} else {
				//此时requestType为null,非ajax请求
				log.info("未登录非ajax请求(浏览器)");
				//跳转到配置的loginUrl页面
				saveRequestAndRedirectToLogin(request, response);
			}
		} else {
			if (AJAX_SIGN.equals(requestType)) {
				log.info("已登录ajax请求");
				httpServletResponse.setCharacterEncoding("UTF-8");
				//setContentType("application/json");
				httpServletResponse.getWriter().write("您没有足够权限");
			} else {
				//此时requestType为null,非ajax请求
				log.info("已登录非ajax请求(浏览器)");
				//获取配置的unauthorizedUrl页面路径
				String unauthorizedUrl = getUnauthorizedUrl();
				//存在内容,跳转到配置的unauthorizedUrl页面
				if (StringUtils.hasText(unauthorizedUrl)) {
					WebUtils.issueRedirect(request, response, unauthorizedUrl);
				} else {
					log.info("请求拒绝401");
					WebUtils.toHttp(response).sendError(401);
				}
			}
		}
		return false;
	}


	@Override
	public boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) {
		//获取该请求路径需要的权限集合,即配置在perms[]中括号内的内容(写在shiro.xml配置文件中或者自定义类中)
		String[] permsArray = (String[]) mappedValue;
		//未配置权限,直接返回
		if (permsArray == null || permsArray.length == 0) {
			return true;
		}
		//将该请求路径保存为set集合
		Set<String> perms = CollectionUtils.asSet(permsArray);
		//获取当前的subject
		Subject subject = getSubject(request, response);
		//设置验证规则,此时规则为:登录用户具有一条请求路径的权限即可,默认为登录用户需要具备请求路径的所有权限
		for (String perm : perms) {
			if (subject.isPermitted(perm)) {
				return true;
			}
		}
		return false;
	}
}

大概就是这个样子,在controller写个登陆验证就好了

package controller;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.web.util.SavedRequest;
import org.apache.shiro.web.util.WebUtils;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;

/**
 * @ClassName UserController
 * @Description TODO
 * @Author shuai
 * @Date 2018/8/6 17:51
 * @Version 1.0
 **/
@Controller
@RequestMapping("user")
public class UserController {

    @ResponseBody
    @RequestMapping(value="login", produces = {"application/json;charset=UTF-8"})
    public Object login(){
        return "请登录";
    }

	@ResponseBody
	@RequestMapping("validate")
	public Object validate(HttpServletRequest request, String username, String password) {
		Subject subject = SecurityUtils.getSubject();
		//UsernamePasswordToken token = new UsernamePasswordToken(username, password);
		UsernamePasswordToken token = new UsernamePasswordToken("zhangsan", "123456");
		int code;
		String message;
		String requestUrl = null;
		try {
			subject.login(token);
			//如果是因为访问其他路径儿跳转到登录页面,savedRequest将有值即想要访问的页面
			SavedRequest savedRequest = WebUtils.getSavedRequest(request);
			if (savedRequest != null) {
				//获取之前访问的路径
				requestUrl = savedRequest.getRequestUrl();
			} else {
				//获取根路径,用来获取首页地址
				requestUrl = request.getContextPath();
			}
		} catch (Exception e) {
		}
		return null;
	}

	@RequestMapping("message")
	public String message() {
		return "message";
	}
}

还有很多细致的东西,自定义异常类啊,跳转到原来的访问路径啊,记住登陆啊之类的,慢慢学习吧

shiro需要引用的包pom.xml

<properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>1.7</maven.compiler.source>
        <maven.compiler.target>1.7</maven.compiler.target>

        <spring-version>4.3.13.RELEASE</spring-version>
        <shiro-version>1.3.2</shiro-version>
        <freemarker-version>2.3.23</freemarker-version>

    </properties>

    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
            <version>1.7.25</version>
        </dependency>

        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>3.1.0</version>
        </dependency>

        <!--spring相关包-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>${spring-version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>${spring-version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>${spring-version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
            <version>${spring-version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-beans</artifactId>
            <version>${spring-version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aop</artifactId>
            <version>${spring-version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context-support</artifactId>
            <version>${spring-version}</version>
        </dependency>
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <version>1.8.13</version>
        </dependency>

        <!-- shiro相关包 -->
        <dependency>
            <groupId>org.apache.shiro</groupId>
            <artifactId>shiro-core</artifactId>
            <version>${shiro-version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.shiro</groupId>
            <artifactId>shiro-spring</artifactId>
            <version>${shiro-version}</version>
        </dependency>

        <!-- freemarker包 -->
        <dependency>
            <groupId>org.freemarker</groupId>
            <artifactId>freemarker</artifactId>
            <version>${freemarker-version}</version>
        </dependency>

    </dependencies>

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Vue.js 是一个用于构建用户界面的渐进式 JavaScript 框架,而Shiro是一个用于身份验证、授权和会话管理的强大的 Java 安全框架。在Vue.js中使用Shiro可以提供安全性和权限控制方面的支持。下面是一个使用Vue.js和Shiro的基本示例: 1. 配置Shiro后端 首先,需要在后端配置Shiro,包括身份验证和授权规则。这可以在Java的后端应用程序中完成,例如使用Spring Boot和Shiro的结合。 2. 创建登录页面 在Vue.js中,可以创建一个登录页面,用于用户输入用户名和密码。可以使用Vue组件来构建这个页面,并通过Vue的双向数据绑定来获取用户输入的用户名和密码。 3. 发起登录请求 在Vue组件中,可以使用axios等工具库来发起登录请求。将用户输入的用户名和密码发送到后端进行验证。如果验证成功,后端可以生成并返回一个令牌(token)给前端。 4. 保存令牌 在前端接收到令牌后,可以将其保存在本地存储中,例如localStorage或sessionStorage。这样,在后续的请求中,可以将令牌添加到请求头中,以便后端进行身份验证。 5. 创建权限控制组件 在Vue.js中,可以创建一个权限控制组件,用于控制不同页面或操作的访问权限。该组件可以通过检查本地存储中的令牌和后端进行通信,来确定当前用户是否有权限执行某个操作或访问某个页面。 需要注意的是,以上只是一个简单的示例,实际上,使用Vue.js和Shiro进行身份验证和授权会涉及到更多的细节和安全性考虑。具体实现方式还需要根据具体的项目需求和后端框架来进行调整。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值