文档章节

项目中用到Shiro安全配置用于系统的登录和权限认证

EDIAGD
 EDIAGD
发布于 2013/02/01 10:16
字数 1400
阅读 3843
收藏 18
点赞 2
评论 0

自己的项目中很多都用到了Shiro的配置来管理验证登录和权限认证,所以自己简单的小结一下,这里暂时只解释登录验证这一块。

(1)首先在项目的WEB-INF目录下的web.xml配置中:

加上

<!-- Shiro Security filter -->
    <filter>
        <filter-name>shiroFilter</filter-name>
        <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>shiroFilter</filter-name>
        <url-pattern>*.htm</url-pattern>
        <dispatcher>REQUEST</dispatcher>
        <dispatcher>FORWARD</dispatcher>
    </filter-mapping>
    <filter-mapping>
        <filter-name>shiroFilter</filter-name>
        <url-pattern>*.json</url-pattern>
        <dispatcher>REQUEST</dispatcher>
        <dispatcher>FORWARD</dispatcher>
    </filter-mapping>
    <filter-mapping>
        <filter-name>shiroFilter</filter-name>
        <url-pattern>*.jsp</url-pattern>
        <dispatcher>REQUEST</dispatcher>
        <dispatcher>FORWARD</dispatcher>
    </filter-mapping>
    <!-- Shiro Security filter -->

上面的配置是对请求地址后缀的过滤和转发

这里我的欢迎页的配置直接配置login.jsp了。还是在web.xml中最后加上

 <welcome-file-list>
        <welcome-file>login.jsp</welcome-file>
    </welcome-file-list>

 

(2)在项目的上下文配置applicationContext.xml中加上:

 <import resource="security/applicationContext-shiro.xml" />

这样的话,就能引入applicationContext-shiro.xml的配置,在这个配置中

全文配置如下:

<?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:util="http://www.springframework.org/schema/util"
	   xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-2.0.xsd"
	   default-lazy-init="true">

	<description>Shiro安全配置</description>

	<!-- Shiro's main business-tier object for web-enabled applications -->
	<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
		<property name="realm" ref="shiroDbRealm" />
		<property name="cacheManager" ref="shiroEhcacheManager" />
	</bean>

	<!-- 項目自定义的Realm -->
	<bean id="shiroDbRealm" class="com.baishi.website.User.MyDbRealm">
		<property name="userService" ref="userService"/>
		<!-- 可配置cache token<->认证信息的cache,用于REST等需要频繁认证的场景 -->
		<!--<property name="authorizationCachingEnabled" value="true"/>-->
	</bean>

	<bean id="myAuthc" class="com.baishi.website.base.filter.MyFormAuthenticationFilter"/>

	<!-- Shiro Filter -->
	<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
		<property name="securityManager" ref="securityManager" />
		<property name="loginUrl" value="/login.htm" />
		<property name="successUrl" value="/admin.htm" />
		<property name="unauthorizedUrl" value="/unauthorized.htm"/>
		<property name="filters">
			<util:map>
				<entry key="myAuthc" value-ref="myAuthc"/>
			</util:map>
		</property>
		<property name="filterChainDefinitions">
			<value>
				/logout.htm = logout
				/** = myAuthc
			</value>
		</property>
	</bean>

	<!-- 用户授权信息Cache, 采用EhCache -->
	<bean id="shiroEhcacheManager" class="org.apache.shiro.cache.ehcache.EhCacheManager">
		<property name="cacheManagerConfigFile" value="classpath:security/ehcache-shiro.xml"/>
	</bean>

	<!-- 保证实现了Shiro内部lifecycle函数的bean执行 -->
	<bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor"/>

	<!-- AOP式方法级权限检查  -->
	<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>

这里面我们关注的是:項目自定义的Realm,在我的目录下com.baishi.website.User.MyDbRealm找到 MyDbRealm这个类

MyDbRealm类的代码如下:

package com.baishi.website.User;

import com.baishi.website.entity.Users;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;

public class MyDbRealm extends AuthorizingRealm {

	private UserService userService;

	/**
	 * 认证回调函数,登录时调用.
	 */
	@Override
	protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
		UsernamePasswordToken upToken = (UsernamePasswordToken) token;
		Users user = userService.findUserByLoginName(upToken.getUsername());
		if (user == null) {
			throw new UnknownAccountException("No account found for user [" + user.getUsername() + "]");
		}

		return new SimpleAuthenticationInfo(user, user.getPassword(), getName());
	}

	/**
	 * 授权查询回调函数, 进行鉴权但缓存中无用户的授权信息时调用.
	 */
	@Override
	protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
		Users user = (Users) principals.fromRealm(getName()).iterator().next();
		//user = userService.findAuthDetails(user);
		if (user != null) {
			SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
//			for (Role role : user.getRoles()) {
//				//基于Role的权限信息
//				info.addRole(role.getName());
//			}
//			info.addStringPermissions(user.getPermissions());
			return info;
		} else {
			return null;
		}
	}

	public void setUserService(UserService userService) {
		this.userService = userService;
	}
}

其中你只要关注:认证回调函数,登录时调用这个方法,到时候断点到这里看一下验证。

继续解释applicationContext-shiro.xml的配置:其中MyFormAuthenticationFilter这个类是超时的类配置:

代码如下:

package com.baishi.website.base.filter;

import org.apache.ibatis.logging.LogFactory;
import org.apache.shiro.web.filter.authc.FormAuthenticationFilter;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class MyFormAuthenticationFilter extends FormAuthenticationFilter {


static {
LogFactory.useStdOutLogging();
}


@Override
protected void saveRequestAndRedirectToLogin(ServletRequest request, ServletResponse response) throws IOException {
HttpServletRequest request1 = (HttpServletRequest) request;
HttpServletResponse response1 = (HttpServletResponse) response;
String uri = request1.getRequestURI();
if (uri.endsWith(".json")) {
response1.setHeader("sessionstatus", "timeout");
} else {
saveRequest(request);
redirectToLogin(request, response);
}
}
}

 

继续解释配置中<property name="loginUrl" value="/login.htm" />

<property name="successUrl" value="/admin.htm" />

两个属性对应的是登录和成功登录后的两个页面,这里我是在webapp根目录的两个页面:

其中login,jsp的页面代码:

<%@ page language="java" contentType="text/html" pageEncoding="UTF-8"%>
<%@taglib prefix="shiro" uri="http://shiro.apache.org/tags" %>

<%
    String path = request.getContextPath();
    String basePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + path + "/";
%>
<html>
<head>
  <base href="<%=basePath%>">
  <title>博客后台登陆</title>
    <shiro:authenticated>
    <script type="text/javascript">
        window.location.href = 'index.htm';
    </script>
    </shiro:authenticated>
</head>

<body>
<p>用户登录</p>

 <form id="form1" name="form1" method="post" action="login.htm">
<input type="hidden" name="method" value="login" />
  <table width="335" height="84" border="0" cellpadding="1" cellspacing="1">
    <tr>
      <td>用户名:</td>
      <td><label>
        <input type="text" name="username" id="username" />
      </label></td>
    </tr>
    <tr>
      <td>密码:</td>
      <td><label>
        <input type="password" name="password" id="password" />
      </label></td>
    </tr>
    <tr>
      <td><label>
        <input type="submit" name="button" id="button" value="登录" />
      </label></td>
      <td><label></label></td>
    </tr>
  </table>
</form>
<p>&nbsp; </p>
</body>

</html>

其中引入shiro的标签,并且

<shiro:authenticated>
    <script type="text/javascript">
        window.location.href = 'index.htm';
    </script>
    </shiro:authenticated>

重定向到index.htm这个页面。

另外在applicationContext-shiro.xml的配置中引入

<!-- 用户授权信息Cache, 采用EhCache -->
<bean id="shiroEhcacheManager" class="org.apache.shiro.cache.ehcache.EhCacheManager">
<property name="cacheManagerConfigFile" value="classpath:security/ehcache-shiro.xml"/>
</bean>

ehcache-shiro.xml的配置如下:

<ehcache updateCheck="false" name="shiroCache">

    <defaultCache
            maxElementsInMemory="10000"
            eternal="false"
            timeToIdleSeconds="120"
            timeToLiveSeconds="120"
            overflowToDisk="false"
            diskPersistent="false"
            diskExpiryThreadIntervalSeconds="120"
            />
</ehcache>

到此 applicationContext-shiro.xml的配置就完成了。

现在实际操作的时候,在用户的Controller类中,我们写上简单代码:

 
package com.baishi.website.User;

import com.alibaba.fastjson.JSON;
import com.baishi.website.base.support.BaseControllerSupport;
import com.baishi.website.entity.Users;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.List;
import java.util.Map;

@Controller
@RequestMapping
public class UserController extends BaseControllerSupport {
   /**
     * 用户登录后台
     */
    @RequestMapping(value = "/login", method = RequestMethod.POST)
    public String home(){
        return  "login";
    }

    @RequestMapping(value = "/login", method = RequestMethod.GET)
    public String login() {
        return "login";
    }

    @RequestMapping(value = {"admin","index"})
    public String admin() {
        return "admin";
    }
}

最后还要说的是在MyDbRealm类中findUserByLoginName()这个方法,自己简单的在service层写一个根据用户名查询数据库的方法就行了,在xml 中的查询语句:

  <select id="findByLoginName" parameterType="String" resultType="Users">
SELECT
*
FROM users
WHERE
username=#{username}
LIMIT 1
</select>

到此就简单的介绍了,用shiro验证登录的配置。解释一下整个过程的流程吧,启动tomcat,首先进入web.xml中过滤→到Controller类中转到视图页面login.jsp→进入了登录的页面,填入信息提交→到MyDbRealm类中验证回调的方法→验证成功后重定向到主页admin.htm

最后贴两张登录的图:

 

后续有很多开发填坑的文章发布,如果对你有帮助,请支持和加关注一下

http://e22a.com/h.05ApkG?cv=AAKHZXVo&sm=339944

https://shop119727980.taobao.com/?spm=0.0.0.0 

© 著作权归作者所有

共有 人打赏支持
EDIAGD
粉丝 48
博文 147
码字总数 58327
作品 0
嘉定
后端工程师
Shiro权限控制框架入门1:Shiro的认证流程以及基本概念介绍

前言:我在最开始学习Shiro这个框架时,在网上搜索到的一个介绍比较全面的教程是:《跟我学Shiro》系列教程。但是在我看了他写的前几篇文章后,我发现虽然他在这个系列教程中把shiro的一些特...

pangfc ⋅ 2017/01/06 ⋅ 0

Apache Shiro 快速入门教程,shiro 基础教程

第一部分 什么是Apache Shiro 1、什么是 apache shiro : Apache Shiro是一个功能强大且易于使用的Java安全框架,提供了认证,授权,加密,和会话管理 如同 spring security 一样都是是一个权...

kevin728971010 ⋅ 2016/10/25 ⋅ 3

Shiro和Spring Security对比

Shiro简介 Apache Shiro是Java的一个安全框架。目前,使用Apache Shiro的人越来越多,因为它相当简单,对比Spring Security,可能没有Spring Security做的功能强大,但是在实际工作时可能并不...

有余力则学文 ⋅ 04/27 ⋅ 0

springboot系列(二):Apache Shiro安全框架的简单使用

上一篇文章中实践了原始方式实现的登录验证的过程,了解了关于登录验证的一些简单原理。然而在实际项目的开发中,这种方式并不能满足实际安全的需求,而是借助一些框架来实现。目前,Apache ...

ijustdarren ⋅ 2017/11/15 ⋅ 0

【转】将Shiro作为应用的权限基础框架

Shiro 是 JAVA 世界中新近出现的权限框架,较之 JAAS 和 Spring Security,Shiro 在保持强大功能的同时,还在简单性和灵活性方面拥有巨大优势。本文就带领读者一睹 Shiro 的风采。 可能大家早...

红薯 ⋅ 2010/04/02 ⋅ 8

Jeesite中shiro的用法讲解

前言 Apache Shiro 是一个框架,可用于身份验证和授权。虽然这两个术语代表的是不同的含义,但出于它们在应用程序安全性方面各自的角色考虑,它们有时会被交换使用。 身份验证 指的是验证用户...

Y幕徐 ⋅ 2017/07/14 ⋅ 0

让Apache Shiro保护你的应用[转]

尝试保护你的应用时,你是否有过挫败感?是否觉得现有的Java安全解决方案难以使用,只会让你更糊涂?本文介绍的Apache Shiro,是一个不同寻常的Java安全框架,为保护应用提供了简单而强大的方...

hhs ⋅ 2011/05/27 ⋅ 2

让Apache Shiro保护你的应用

在尝试保护你的应用时,你是否有过挫败感?是否觉得现有的Java安全解决方案难以使用,只会让你更糊涂?本文介绍的Apache Shiro,是一个不同寻常的Java安全框架,为保护应用提供了简单而强大的...

游宵 ⋅ 2014/05/09 ⋅ 1

SSM(三)Shiro使用详解

前言 相比有做过企业级开发的童鞋应该都有做过权限安全之类的功能吧,最先开始我采用的是建,,,之后在拦截器中对每一个请求进行拦截,再到数据库中进行查询看当前用户是否有该权限,这样的设...

crossoverJie ⋅ 2016/07/15 ⋅ 19

让Apache Shiro保护你的应用

什么是Apache Shiro? Apache Shiro(发音为“shee-roh”,日语“堡垒(Castle)”的意思)是一个强大易用的Java安全框架,提供了认证、授权、加密和会话管理功能,可为任何应用提供安全保障...

heroShane ⋅ 2014/02/09 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

内核线程、轻量级进程、用户线程

线程与进程概念 在现代操作系统中,进程支持多线程。 进程是资源管理的最小单元; 线程是程序执行的最小单元。 即线程作为调度和分配的基本单位,进程作为资源分配的基本单位 一个进程的组成...

117 ⋅ 15分钟前 ⋅ 0

elasticsearch2.4.6升级为elasticsearch-5.5.0的经历

将elasticsearch-5.5.0 中的配置 path.data 指向原来的数据路径 即 path.data: /usr/local/src/elasticsearch-2.4.6/data 注意: elasticsearch-5.5.0 需要将jdk版本升级到1.8...

晨猫 ⋅ 16分钟前 ⋅ 1

lvm讲解 磁盘故障小案例

1

oschina130111 ⋅ 20分钟前 ⋅ 0

那些提升开发人员工作效率的在线工具

本文转载自公众号 Hollis 作为一个Java开发人员,经常要和各种各样的工具打交道,除了我们常用的IDE工具以外,其实还有很多工具是我们在日常开发及学习过程中要经常使用到的。 Hollis偏爱使用...

时刻在奔跑 ⋅ 32分钟前 ⋅ 0

restful风格 实现DELETE PUT请求 的web.xml的配置

import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframe......

泉天下 ⋅ 38分钟前 ⋅ 0

Shell数组

Shell数组 Shell在编程方面比Windows批处理强大很多,无论是在循环、运算。 bash支持一维数组(不支持多维数组),并且没有限定数组的大小。类似与C语言,数组元素的下标由0开始编号。获取数...

蜗牛奔跑 ⋅ 47分钟前 ⋅ 0

nmap为了开发方便 可以做简单的修改

因为nmap扫描是默认使用的是nse脚本,但是在开发的过程中需要修改后缀(主要是因为后缀为lua才能显示高亮,所以这里用一个取巧的办法) nse_main.lua文件中我们找到如下代码 local t, path = cn...

超级大黑猫 ⋅ 51分钟前 ⋅ 0

springmvc获取axios数据为null情况

场景:前端用了vue没有用ajax与后台通信,用了axios,但是在代码运行过程中发现axios传递到后台的值接受到数据为null。 问题原因:此处的问题在与axios返回给后台的数据为json类型的,后台接...

王子城 ⋅ 53分钟前 ⋅ 0

hadoop技术入门学习之发行版选择

经常会看到这样的问题:零基础学习hadoop难不难?有的人回答说:零基础学习hadoop,没有想象的那么难,也没有想象的那么容易。看到这样的答案不免觉得有些尴尬,这个问题算是白问了,因为这个...

左手的倒影 ⋅ 53分钟前 ⋅ 0

806. Number of Lines To Write String - LeetCode

Question 806. Number of Lines To Write String Solution 思路:注意一点,如果a长度为4,当前行已经用了98个单元,要另起一行。 Java实现: public int[] numberOfLines(int[] widths, Str...

yysue ⋅ 今天 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部