一、pom.xml

 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.sh</groupId>
<artifactId>shirotest</artifactId>
<packaging>war</packaging>
<version>0.0.1-SNAPSHOT</version>
<name>shirotest Maven Webapp</name>
<url>http://maven.apache.org</url> <dependencies> <!-- https://mvnrepository.com/artifact/org.apache.shiro/shiro-all -->
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-all</artifactId>
<version>1.2.2</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.commons/commons-lang3 -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.4</version>
</dependency> <dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/jstl/jstl -->
<dependency>
<groupId>jstl</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-aop -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>3.2.0.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-aspects -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>3.2.0.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-beans -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>3.2.0.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>3.2.0.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-context-support -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>3.2.0.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-core -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>3.2.0.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-expression -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-expression</artifactId>
<version>3.2.0.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-instrument -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-instrument</artifactId>
<version>3.2.0.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-instrument-tomcat -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-instrument-tomcat</artifactId>
<version>3.2.0.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-jdbc -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>3.2.0.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-orm -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>3.2.0.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-oxm -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-oxm</artifactId>
<version>3.2.0.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-struts -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-struts</artifactId>
<version>3.2.0.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-test -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>3.2.0.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-tx -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>3.2.0.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-web -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>3.2.0.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>3.2.0.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc-portlet -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc-portlet</artifactId>
<version>3.2.0.RELEASE</version>
</dependency>
</dependencies>
<build>
<finalName>shirotest</finalName>
</build>
</project>

二、SpringMvc.xml

 <beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">
<!-- 启动注解驱动的Spring MVC功能,注册请求url和注解POJO类方法的映射-->
<mvc:annotation-driven />
<!-- 启动包扫描功能,以便注册带有@Controller、@Service、@repository、@Component等注解的类成为spring的bean -->
<context:component-scan base-package="com.**.controller" />
<mvc:default-servlet-handler/>
<!-- 对模型视图名称的解析,在请求时模型视图名称添加前后缀 -->
<!-- <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" p:prefix="/" p:suffix=".jsp" /> -->
<bean
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix">
<value>/</value>
</property>
<property name="suffix">
<value>.jsp</value>
</property>
</bean> <!-- shiro注解启用,不可配置在shiro.xml中 -->
<bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator" depends-on="lifecycleBeanPostProcessor"/>
<bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">
<property name="securityManager" ref="securityManager"/>
</bean> <!-- shiro注解拦截未授权时跳转页面 -->
<bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
<property name="exceptionMappings">
<props>
<prop key="org.apache.shiro.authz.AuthorizationException">
/meishouquan <!-- //捕获该异常时跳转的路径 -->
</prop> </props>
</property>
</bean>
</beans>

三、web.xml

 <?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
<session-config>
<session-timeout>120</session-timeout>
</session-config>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring-*.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>*.jpg</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>*.js</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>*.css</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>*.docx</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>spring</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>spring</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping> <!--
配置Shiro过滤器
这里filter-name必须对应spring-shiro.xml中定义的<bean id="shiroFilter"/>
使用[/*]匹配所有请求,保证所有的可控请求都经过Shiro的过滤
通常会将此filter-mapping放置到最前面(即其他filter-mapping前面),以保证它是过滤器链中第一个起作用的
-->
<filter>
<filter-name>shiroFilter</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
<init-param>
<!-- 缺省为false,表示由SpringApplicationContext管理生命周期,置为true则表示由ServletContainer管理 -->
<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>

四、spring-shiro.xml

 <beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd"> <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
<!-- 指定Shiro验证用户登录的类为自定义的Realm(若有多个Realm,可使用[realms]属性代替) -->
<property name="realm">
<bean class="com.sh.realm.MyRealm"/>
</property>
<!--
Shiro默认会使用Servlet容器的Session,此时修改超时时间的话,可以修改web.xml或者这里自定义的MyRealm
而若想使用Shiro原生Session则可以设置sessionMode属性为native,此时修改超时时间则只能修改MyRealm
-->
<!-- <property name="sessionMode" value="native"/> -->
</bean> <!-- Shiro主过滤器本身功能十分强大,其强大之处就在于它支持任何基于URL路径表达式的、自定义的过滤器的执行 -->
<!-- Web应用中,Shiro可控制的Web请求必须经过Shiro主过滤器的拦截,并且Shiro对基于Spring的Web应用提供了完美的支持 -->
<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
<!-- Shiro的核心安全接口,这个属性是必须的 -->
<property name="securityManager" ref="securityManager"/>
<!-- 要求登录时的链接(可根据项目的URL进行替换),非必须的属性,默认会找Web工程根目录下的[/login.jsp] -->
<property name="loginUrl" value="/login.jsp"/>
<!-- 登录成功后要跳转的连接(本例中此属性用不到,因为登录成功后的处理逻辑已在LoginController中硬编码为main.jsp) -->
<!-- <property name="successUrl" value="/system/main"/> -->
<!-- 用户访问未授权的资源时,跳转页面-->
<property name="unauthorizedUrl" value="/meishouquan.jsp"/>
<!--拦截配置-->
<property name="filterChainDefinitions">
<value>
/admin/list** = authc,perms[admin:manage,admin:add] <!-- 必须登陆,并且具有[]里的权限才可访问 -->
<!-- /admin/list** = authc,roles[admin] --> <!-- 必须登陆,并且具有[]里的角色才可访问 -->
/user/info-anon** = anon<!-- 无需登录 -->
/user/info** = authc<!-- 需要登陆 -->
</value>
</property>
</bean> <!-- 保证实现了Shiro内部lifecycle函数的bean执行 -->
<!-- http://shiro.apache.org/static/1.2.1/apidocs/org/apache/shiro/spring/LifecycleBeanPostProcessor.html -->
<bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor"/> <!--开启Shiro的注解(比如@RequiresRoles、@RequiresPermissions) 配置以下两个bean即可实现此功能--> <!-- 注意:**下面配置只能在spring.xml中配置生效,必须保证在加载第一个xml时加载此配置 --> <!-- <bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator" depends-on="lifecycleBeanPostProcessor"/>
<bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">
<property name="securityManager" ref="securityManager"/>
</bean> --> </beans>

五、添加页面,点击下载

六、添加Controller代码

 package com.sh.controller;

 import java.io.IOException;

 import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession; import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.builder.ReflectionToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.ExcessiveAttemptsException;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.LockedAccountException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.annotation.RequiresGuest;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.apache.shiro.authz.annotation.RequiresRoles;
import org.apache.shiro.authz.annotation.RequiresUser;
import org.apache.shiro.subject.Subject;
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.RequestMethod;
import org.springframework.web.servlet.view.InternalResourceViewResolver; /**
* SpringMVC-3.2.4整合Shiro-1.2.2
*/
@Controller
@RequestMapping("mydemo")
public class ShiroUserController {
@RequestMapping(value="/test", method=RequestMethod.GET)
public void test(String username, String password, HttpServletRequest request,HttpServletResponse response) throws IOException{
//Subject currentUser = SecurityUtils.getSubject();
// System.out.println(currentUser.);
/*System.out.println(currentUser.isPermitted("admin:manage1"));//判断是否有指定权限
System.out.println(currentUser.hasRole("admin1"));//判断是否有指定角色*/
Object principal = SecurityUtils.getSubject().getPrincipal();//获得当前登录用户名
response.getWriter().print(principal);
}
@RequestMapping("/logout")
public String logout(HttpSession session){
String currentUser = (String)session.getAttribute("currentUser");
System.out.println("用户[" + currentUser + "]准备登出");
SecurityUtils.getSubject().logout();
System.out.println("用户[" + currentUser + "]已登出");
return InternalResourceViewResolver.REDIRECT_URL_PREFIX + "/login.jsp";
} @RequestMapping(value="/login", method=RequestMethod.POST)
public String login(String username, String password, HttpServletRequest request){
System.out.println("-------------------------------------------------------");
String rand = (String)request.getSession().getAttribute("rand");
String captcha = WebUtils.getCleanParam(request, "captcha");
System.out.println("用户["+username+"]登录时输入的验证码为["+captcha+"],HttpSession中的验证码为["+rand+"]");
if(!StringUtils.equals(rand, captcha)){
request.setAttribute("message_login", "验证码不正确");
return InternalResourceViewResolver.FORWARD_URL_PREFIX + "/";
}
UsernamePasswordToken token = new UsernamePasswordToken(username, password);
// token.setRememberMe(true);
System.out.print("为验证登录用户而封装的Token:");
System.out.println(ReflectionToStringBuilder.toString(token, ToStringStyle.MULTI_LINE_STYLE));
//获取当前的Subject
Subject currentUser = SecurityUtils.getSubject();
try {
//在调用了login方法后,SecurityManager会收到AuthenticationToken,并将其发送给已配置的Realm执行必须的认证检查
//每个Realm都能在必要时对提交的AuthenticationTokens作出反应
//所以这一步在调用login(token)方法时,它会走到MyRealm.doGetAuthenticationInfo()方法中,具体验证方式详见此方法
System.out.println("对用户[" + username + "]进行登录验证...验证开始");
currentUser.login(token);
System.out.println("对用户[" + username + "]进行登录验证...验证通过");
}catch(UnknownAccountException uae){
System.out.println("对用户[" + username + "]进行登录验证...验证未通过,未知账户");
request.setAttribute("message_login", "未知账户");
}catch(IncorrectCredentialsException ice){
System.out.println("对用户[" + username + "]进行登录验证...验证未通过,错误的凭证");
request.setAttribute("message_login", "密码不正确");
}catch(LockedAccountException lae){
System.out.println("对用户[" + username + "]进行登录验证...验证未通过,账户已锁定");
request.setAttribute("message_login", "账户已锁定");
}catch(ExcessiveAttemptsException eae){
System.out.println("对用户[" + username + "]进行登录验证...验证未通过,错误次数过多");
request.setAttribute("message_login", "用户名或密码错误次数过多");
}catch(AuthenticationException ae){
//通过处理Shiro的运行时AuthenticationException就可以控制用户登录失败或密码错误时的情景
System.out.println("对用户[" + username + "]进行登录验证...验证未通过,堆栈轨迹如下");
ae.printStackTrace();
request.setAttribute("message_login", "用户名或密码不正确");
}
//验证是否登录成功
if(currentUser.isAuthenticated()){
System.out.println("用户[" + username + "]登录认证通过(这里可进行一些认证通过后的系统参数初始化操作)");
return "main";
}else{
token.clear();
return InternalResourceViewResolver.FORWARD_URL_PREFIX + "/";
}
}
//属于admin角色
//@RequiresRoles("admin")
//必须同时属于user和admin角色
@RequiresRoles({"user","admin"})
//属于user或者admin之一;修改logical为OR 即可
//@RequiresRoles(value={"user","admin"},logical=Logical.OR)
@RequestMapping(value="/useRoles")
public void requiresRoles(HttpServletRequest request, HttpServletResponse response){
System.out.println("必须拥有指定角色");
}
//符合index:hello权限要求
@RequiresPermissions("admin:manage")
//必须同时复核index:hello和index:world权限要求
//@RequiresPermissions({"index:hello","index:world"})
//符合index:hello或index:world权限要求即可
//@RequiresPermissions(value={"index:hello","index:world"},logical=Logical.OR)
@RequestMapping(value="/useper")
public void requiresPermissions(HttpServletRequest request, HttpServletResponse response){
System.out.println("必须拥有指定权限");
}
/* 验证用户是否被记忆,user有两种含义:
一种是成功登录的(subject.isAuthenticated() 结果为true);
另外一种是被记忆的(subject.isRemembered()结果为true)。*/
@RequiresUser
@RequestMapping(value="/islogin")
public void requiresUser(HttpServletRequest request, HttpServletResponse response){
System.out.println("必须登录或者记住登录的");
}
//必须游客访问
@RequiresGuest
@RequestMapping(value="/isguest")
public void requiresGuest(HttpServletRequest request, HttpServletResponse response){
System.out.println("必须游客");
}
}

七、添加Realm代码

 package com.sh.realm;

 import org.apache.commons.lang3.builder.ReflectionToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import org.apache.shiro.SecurityUtils;
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.authc.UsernamePasswordToken;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.subject.Subject; /**
* 自定义的指定Shiro验证用户登录的类
* 这里定义了两个用户:admin(拥有admin角色和admin:manage权限)、user(无任何角色和权限)
*/
public class MyRealm extends AuthorizingRealm {
/**
* 为当前登录的Subject授予角色和权限
* -----------------------------------------------------------------------------------------------
* 经测试:本例中该方法的调用时机为需授权资源被访问时
* 经测试:并且每次访问需授权资源时都会执行该方法中的逻辑,这表明本例中默认并未启用AuthorizationCache
* 个人感觉若使用了Spring3.1开始提供的ConcurrentMapCache支持,则可灵活决定是否启用AuthorizationCache
* 比如说这里从数据库获取权限信息时,先去访问Spring3.1提供的缓存,而不使用Shior提供的AuthorizationCache
* -----------------------------------------------------------------------------------------------
*/
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals){
//获取当前登录的用户名
String currentUsername = (String)super.getAvailablePrincipal(principals); /* UsernamePasswordToken token = new UsernamePasswordToken(currentUsername, "admin");
SecurityUtils.getSubject().login(token);*/ ////从数据库中获取当前登录用户的详细信息
//List<String> roleList = new ArrayList<String>();
//List<String> permissionList = new ArrayList<String>();
//User user = userService.getByUsername(currentUsername);
//if(null != user){
// //实体类User中包含有用户角色的实体类信息
// if(null!=user.getRoles() && user.getRoles().size()>0){
// //获取当前登录用户的角色
// for(Role role : user.getRoles()){
// roleList.add(role.getName());
// //实体类Role中包含有角色权限的实体类信息
// if(null!=role.getPermissions() && role.getPermissions().size()>0){
// //获取权限
// for(Permission pmss : role.getPermissions()){
// if(StringUtils.isNotBlank(pmss.getPermission())){
// permissionList.add(pmss.getPermission());
// }
// }
// }
// }
// }
//}else{
// throw new AuthorizationException();
//}
////为当前用户设置角色和权限
//SimpleAuthorizationInfo simpleAuthorInfo = new SimpleAuthorizationInfo();
//simpleAuthorInfo.addRoles(roleList);
//simpleAuthorInfo.addStringPermissions(permissionList);
//实际中可能会像上面注释的那样,从数据库或缓存中取得用户的角色和权限信息
SimpleAuthorizationInfo simpleAuthorInfo = new SimpleAuthorizationInfo();
if(null!=currentUsername && "admin".equals(currentUsername)){
//添加一个角色,不是配置意义上的添加,而是证明该用户拥有admin角色
simpleAuthorInfo.addRole("admin");
simpleAuthorInfo.addRole("user");
//添加权限
//simpleAuthorInfo.addStringPermission("admin:manage");
//simpleAuthorInfo.addStringPermission("admin:add");
simpleAuthorInfo.addStringPermission("*");//拥有所有权限
System.out.println("已为用户[jadyer]赋予了[admin]角色和[admin:manage]权限");
return simpleAuthorInfo;
}
if(null!=currentUsername && "fangke".equals(currentUsername)){
System.out.println("当前用户[xuanyu]无授权(不需要为其赋予角色和权限)");
return simpleAuthorInfo;
}
//若该方法什么都不做直接返回null的话
//就会导致任何用户访问/admin/listUser.jsp时都会自动跳转到unauthorizedUrl指定的地址
//详见applicationContext.xml中的<bean id="shiroFilter">的配置
return null;
} /**
* 验证当前登录的Subject
* 经测试:本例中该方法的调用时机为LoginController.login()方法中执行Subject.login()的时候
*/
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authcToken) throws AuthenticationException {
//获取基于用户名和密码的令牌
//实际上这个authcToken是从LoginController里面currentUser.login(token)传过来的
//两个token的引用都是一样的,本例中是:org.apache.shiro.authc.UsernamePasswordToken@33799a1e
UsernamePasswordToken token = (UsernamePasswordToken)authcToken;
System.out.print("验证当前Subject时获取到token:");
System.out.println(ReflectionToStringBuilder.toString(token, ToStringStyle.MULTI_LINE_STYLE));
//User user = userService.getByUsername(token.getUsername());
//if(null != user){
// String username = user.getUsername();
// String password = user.getPassword();
// String nickname = user.getNickname();
// AuthenticationInfo authcInfo = new SimpleAuthenticationInfo(username, password, nickname);
// this.setSession("currentUser", user);
// return authcInfo;
//}else{
// return null;
//}
//此处无需比对,比对的逻辑Shiro会做,我们只需返回一个和令牌相关的正确的验证信息
//说白了就是第一个参数填登录用户名,第二个参数填合法的登录密码(可以是从数据库中取到的,本例中为了演示就硬编码了)
//这样一来,在随后的登录页面上就只有这里指定的用户和密码才能通过验证
if("admin".equals(token.getUsername())){
AuthenticationInfo authcInfo = new SimpleAuthenticationInfo("admin", "admin", this.getName());
this.setAuthenticationSession("admin");
return authcInfo;
}
if("user".equals(token.getUsername())){
AuthenticationInfo authcInfo = new SimpleAuthenticationInfo("user", "user", this.getName());
this.setAuthenticationSession("user");
return authcInfo;
}
//没有返回登录用户名对应的SimpleAuthenticationInfo对象时,就会在LoginController中抛出UnknownAccountException异常
return null;
} /**
* 将一些数据放到ShiroSession中,以便于其它地方使用
* 比如Controller里面,使用时直接用HttpSession.getAttribute(key)就可以取到
*/
private void setAuthenticationSession(Object value){
Subject currentUser = SecurityUtils.getSubject();
if(null != currentUser){
Session session = currentUser.getSession();
System.out.println("当前Session超时时间为[" + session.getTimeout() + "]毫秒");//web.xml未配置session时间默认30分钟,配置了按照实际配置为准
session.setTimeout(1000 * 60 * 60 * 2);
// session.setTimeout(1000 * 60);//用户操作时时间顺延
System.out.println("修改Session超时时间为[" + session.getTimeout() + "]毫秒");
session.setAttribute("currentUser", value);
}
}
}

Realm中实现两个方法:

doGetAuthorizationInfo只要访问需要授权的内容,都会进入此方法,查找当前登录用户的权限

doGetAuthenticationInfo调用shiro登录时,会执行此方法

shiro有三种拦截方式,

第一种是xml配置

第二种是注解,我个人比较喜欢使用注解方式,感觉这样配置有针对性

第三种是页面拦截,这种没有写,因为比较简单,百度一下全都有了

本内容参考以下学习总结,感谢。http://jadyer.cn/2013/09/30/springmvc-shiro/

shiro环境搭建及基本操作的更多相关文章

  1. Docker环境搭建以及基本操作

    Docker环境搭建以及基本操作 Docker环境基本搭建: 基础环境:Centos 7.4        IP:192.168.30.117 [root@docker ~]# cat /etc/re ...

  2. 大数据学习(16)—— HBase环境搭建和基本操作

    部署规划 HBase全称叫Hadoop Database,它的数据存储在HDFS上.我们的实验环境依然基于上个主题Hive的配置,参考大数据学习(11)-- Hive元数据服务模式搭建. 在此基础上, ...

  3. ionic项目 环境搭建及基本操作

    一.安装 1.安装node.js 3.安装ionic & cordova: 命令行输入:npm install –g cordova ionic 注:-g表示全局安装,也可以进入指定的目录安装 ...

  4. Spring+SpringMVC+Mybatis+Shiro环境搭建之IDEA下搭建Maven项目

    运行IntelliJ IDEA 2016.3.2(64)编译器新建项目   在弹出的窗体中选择maven,然后勾选要建的maven模板--这里选webApp 然后填入相应的maven项目组信息(Gro ...

  5. Hive环境搭建及基本操作

    伪分布式 一.安装及配置Hive 1.配置HADOOP_HOME和Hive conf 目录hive-env.sh # Set HADOOP_HOME to point to a specific ha ...

  6. Shrio00 Shiro认证登录、权限管理环境搭建

    基础环境准备: JDK -> java version "1.8.0_101" MAVEN -> Apache Maven 3.5.0 1 导入依赖 mysql驱动 m ...

  7. 快速搭建Spring Boot + Apache Shiro 环境

    个人博客网:https://wushaopei.github.io/    (你想要这里多有) 一.Apache Shiro 介绍及概念 概念:Apache Shiro是一个强大且易用的Java安全框 ...

  8. linux的基本操作(LAMP环境搭建)

    LAMP 环境搭建 经过前部分章节的学习,你已经掌握了linux的基础知识了.但是想成为一名系统管理员恐怕还有点难度,因为好多单位招聘这个职位的时候都要求有一定的工作经验.然而真正的经验一天两天是学不 ...

  9. Ubuntu Desktop开发生产环境搭建

    Ubuntu Desktop开发生产环境搭建 1   开发生产环境搭建 在本节内容开始前,先定义一下使用场合,没有哪种系统或者设备是万能的,都有它的优点和缺点,能够在具体的使用场景,根据自身的需求来取 ...

随机推荐

  1. MYSQL 删除语句(数据)

    删除数据(DELETE)     如果你失忆了,希望你能想起曾经为了追求梦想的你.   数据库存储数据,总会有一些垃圾数据,也会有一些不需要用的数据了,这些情况下,我们就可以删除这些数据,释放出一定的 ...

  2. java三大框架——Struts + Hibernate + Spring

    Struts主要负责表示层的显示 Spring利用它的IOC和AOP来处理控制业务(负责对数据库的操作) Hibernate主要是数据持久化到数据库 再用jsp的servlet做网页开发的时候有个 w ...

  3. element table 表格 修改背景为透明并去除边框

    .el-table{ /* 表格字体颜色 */ color:white; /* 表格边框颜色 */ /* border: 0.5px solid #758a99; */ height: 500px; ...

  4. Linux使用wget仿站

    运行命令 $ wget -r -p -np -k www.avatrade.cn 参数说明 -r --recursive(递归) specify recursive download.(指定递归下载) ...

  5. js动态的往表格中加入表单元素

    效果如图: 这里我用的是layui的静态表格,其他框架也是一样的(只要你都表单元素要通过js进行渲染),我的需求是在表单中放了表格的元素,表格中还有表单的元素.表格中的行数据是js动态添加的,正常的添 ...

  6. 查看TensorFlow的版本以及安装路径

    查看TensorFlow的版本以及安装路径 进入到Python环境 import tensorflow as tf tf.__version__ # 查看版本 tf.__path__ # 查看安装路径 ...

  7. PAT Basic 1021 个位数统计 (15 分)

    给定一个 k 位整数 1 (0, ,, d​k−1​​>0),请编写程序统计每种不同的个位数字出现的次数.例如:给定 0,则有 2 个 0,3 个 1,和 1 个 3. 输入格式: 每个输入包含 ...

  8. linux syslog支持 ubuntu

    linux  syslog支持 linux  syslog支持 linux  syslog支持 ??????? https://wenku.baidu.com/view/8cc6b50a0202074 ...

  9. Hutools之http工具类

    Hutools请求网络资源使用的工具类:HttpRequest和HttpResponse Get方式请求数据 Get方式请求数据Map<String,Object> paramMap = ...

  10. windows安装PostgreSQL

    犹豫了一小下,初学不在linux下安装sql,虽然说书上有,还是想记录一下,以后好找 入门的书籍是SQL基础教程第二版,图书馆搜刮来的,毕竟要还 下载页面 http://www.enterprised ...