spring+shiro搭建简单安全框架

一、简介:
shiro是一个安全框架,顾名思义就是对系统的访问进行安全控制,包含用户身份认证(登录),用户权限控制(通过角色,权限字符串等)。
权限里面很关键的两个东西:认证和授权。
  1. 认证没什么好说的,目的就是判断用户的账号密码是否正确之类的,授权的作用嘛,简单的解释就是给用户赋予相应的权限。

  2. 判断一个用户有没有权限访问,无非是拦截URL能否访问,分为以下几个操作

①判断当前URL是否需要拦截,不需要则放行,需要则进入下一步
②判断用户是否已登陆,有则下一步,无则抛出401未认证
④从资源表/权限表读取当前登陆用户的可访问地址,进入下一步判断是否包含用户当前访问的地址,有则放行,无则抛出403无权限。

二、简单搭建
1.maven工程,版本自行选择
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-core</artifactId>
<version>1.3.2</version>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-web</artifactId>
<version>1.3.2</version>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>1.3.2</version>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-ehcache</artifactId>
<version>1.3.2</version>
</dependency>

2.配置web.xml,需要配置shiro特定的过滤器,主要作用是把所有的bean交给spring管理,通过spring容器来管理filter的生命周期,通过spring注入的形式,来代理一个filter执行,主要目的是,找到在spring中维护的目标filter。

<!-- 配置 Shiro 的 Filter -->
<filter>
<description>shiro 权限拦截</description>
<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>

<!-- 指定spring配置文件的位置,配置文件放在resources下 -->

<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:conf/spring/spring-shiro.xml</param-value>
</context-param>

<?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"
xmlns:rsf="http://www.suning.com/schema/rsf"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.suning.com/schema/rsf http://www.suning.com/schema/rsf/rsf.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.2.xsd
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"&gt;
<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
<!-- 必须设置 -->
<property name="securityManager" ref="securityManager"/>
</bean>

<bean id="exceptionResolver" class="com.suning.lcss.common.util.MyExceptionResolver"></bean>
<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
<property name="realm" ref="customRealm" />
</bean>

<!-- 自定义 realm -->
<bean id="customRealm" class="com.suning.lcss.base.shiro.ShiroDbRealm">
</bean>

<!--3.开启Spring AOC Shiro注解支持-->
<bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">
<property name="securityManager" ref="securityManager"/>
</bean>
</beans>

exceptionResolver作用在于统一的异常捕捉。

ShiroDbRealm类中有doGetAuthorizationInfo(AuthenticationToken token) ,doGetAuthenticationInfo两个方法,doGetAuthenticationInfo(PrincipalCollection arg0)作用在于登陆认证,包括用户名和密码的验证,如果不做用户名密码的验证。
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
UsernamePasswordToken upToken =(UsernamePasswordToken)token;
String userName=upToken.getUsername();
return new SimpleAuthenticationInfo(userName,
upToken.getPassword(),getName());

}

/**
 * 授权查询回调函数, 进行鉴权但缓存中无用户的授权信息时调用,负责在应用程序中决定用户的访问控制的方法
 */
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection arg0) {
    UserLoginBean user = (UserLoginBean) SecurityUtils.getSubject().getSession().getAttribute(LcssConstant.LOGIN_COMMAND);
    SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
    info.addRole(user.getRoleCode());
//权限编码
    String authorityStr = CommonUtil.getAuthorityStr(user.getInitialFlag(), user.getRoleCode());

    List<String> idList = new ArrayList<>();
    if(!StringUtil.isNullOrEmpty(authorityStr)){
        idList = Arrays.asList(authorityStr.split(","));
    }       
    info.addStringPermissions(idList);
    return info;
}

doGetAuthorizationInfo(PrincipalCollection arg0),每次controller层调用都会进入这个方法来判断当前用户是否有权限。如果有权限进入方法,没权限拒绝访问。

注解RequiresPermissions的使用:

三、总结:
Shiro可以帮助我们完成:认证、授权、加密、会话管理、与Web集成、缓存等。

Realm是Shiro的核心组建,也一样是两步走,认证和授权,在Realm中的表现为以下两个方法。

认证:doGetAuthenticationInfo,核心作用判断用户名密码是否正确
授权:doGetAuthorizationInfo,核心作用是获取用户的权限字符串,用于后续的判断
Authentication:身份认证/登录,验证用户是不是拥有相应的身份;

Authorization:授权,即权限验证,验证某个已认证的用户是否拥有某个权限;即判断用户是否能做事情,常见的如:验证某个用户是否拥有某个角色。或者细粒度的验证某个用户对某个资源是否具有某个权限;

相关推荐