Shiro整合SpringMVC之web搭建

项目框架:Spring + SpringMvc + Shiro + Mybatis + Redis

本章的源码地址:https://download.csdn.net/download/baidu_24352355/10476943

Shiro认证与授权的在Web中实现

第一步:添加依赖

<!-- shiro -->
   <dependency>
     <groupId>org.apache.shiro</groupId>
     <artifactId>shiro-core</artifactId>
     <version>1.4.0</version>
   </dependency>
   <dependency>
     <groupId>org.apache.shiro</groupId>
     <artifactId>shiro-spring</artifactId>
     <version>1.4.0</version>
   </dependency>


第二步:配置web.xml

<!-- shiro 过滤器 start -->
  <filter>
    <filter-name>shiroFilter</filter-name>
    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
    <!-- 设置true由servlet容器控制filter的生命周期 -->
    <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>
  <!-- shiro 过滤器 end -->

第三步:自定义Realm继承AuthorizingRealm,重写AuthorizationInfo(授权)和AuthenticationInfo(认证)

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

    <bean id="shiroFilter"
          class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
        <property name="securityManager" ref="securityManager"></property>
        <property name="loginUrl" value="login.jsp"></property><!-- 没有登录的用户请求需要登录的页面时自动跳转到登录页面,不是必须的属性,不输入地址的话会自动寻找项目web项目的根目录下的”/login.jsp”页面 -->
        <property name="unauthorizedUrl" value="error.jsp"></property><!-- 没有权限默认跳转的页面 -->
        <property name="filterChainDefinitions">
            <value><!-- 自上到下 --><!-- anon:表示可以匿名使用。 authc:表示需要认证(登录)才能使用,没有参数.  roles["admin,guest"],每个参数通过才算通过,user表示必须存在用户 -->
                /login.jsp = anon
                /subLogin = anon
                /testRoles = roles["admin"]
                /testRoles1 = rolesOr["admin","admin1"]
                /testPerms = perms["user:delete"]
                /testPerms1 = perms["user:delete","user:updata"]
                /* = authc
            </value>
        </property>
        <property name="filters">
            <map>
                <entry key="rolesOr" value-ref="rolesOrFilter" />
            </map>
        </property>
    </bean>

    <!-- 自定义权限filter -->
    <bean id="rolesOrFilter" class="com.shiro.filter.RolesOrFilter" />

    <!-- 创建SecurityManager对象 -->
    <bean id="securityManager"
          class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
        <property name="realm" ref="realm" />
        <property name="sessionManager" ref="sessionManager" />
        <property name="cacheManager" ref="cacheManager" />
        <property name="rememberMeManager" ref="cookieRememberMeManager" />
    </bean>

    <!-- 自定义Realm -->
    <bean id="realm" class="com.shiro.realm.CustomRealm">
        <property name="credentialsMatcher" ref="credentialsMatcher" ></property>
    </bean>

    <bean id="credentialsMatcher" class="org.apache.shiro.authc.credential.HashedCredentialsMatcher">
        <property name="hashAlgorithmName" value="md5" />
        <property name="hashIterations" value="1" />
    </bean>
    <!-- 自定义SessionManager -->
    <bean class="com.shiro.session.CustomSessionManager" id="sessionManager">
        <property name="sessionDAO" ref="redisSessionDao"></property>
    </bean>

    <bean class="com.shiro.session.RedisSessionDao" id="redisSessionDao"></bean>

    <bean class="com.shiro.cache.RedisCacheManager" id="cacheManager"></bean>

    <!-- 自动登录 -->
    <bean class="org.apache.shiro.web.mgt.CookieRememberMeManager" id="cookieRememberMeManager">
        <property name="cookie" ref="cookie"></property>
    </bean>

    <bean class="org.apache.shiro.web.servlet.SimpleCookie" id="cookie">
        <constructor-arg name="name" value="rememberMe" />
        <property name="maxAge" value="20000000" />
    </bean>

</beans>
一些属性的意义:
  • securityManager: 这个属性是必须的。

  • loginUrl: 没有登录的用户请求需要登录的页面时自动跳转到登录页面,不是必须的属性,不输入地址的话会自动寻找项目web项目的根目录下的”/login.jsp”页面。

  • successUrl: 登录成功默认跳转页面,不配置则跳转至”/”。如果登陆前点击的一个需要登录的页面,则在登录自动跳转到那个需要登录的页面。不跳转到此。

  • unauthorizedUrl: 没有权限默认跳转的页面。

Shiro中默认的过滤器:
过滤器名称过滤器类描述
anonorg.apache.shiro.web.filter.authc.AnonymousFilter匿名过滤器
authcorg.apache.shiro.web.filter.authc.FormAuthenticationFilter如果继续操作,需要做对应的表单验证否则不能通过
authcBasicorg.apache.shiro.web.filter.authc.BasicHttpAuthenticationFilter基本http验证过滤,如果不通过,跳转屋登录页面
logoutorg.apache.shiro.web.filter.authc.LogoutFilter登录退出过滤器
noSessionCreationorg.apache.shiro.web.filter.session.NoSessionCreationFilter没有session创建过滤器
permsorg.apache.shiro.web.filter.authz.PermissionsAuthorizationFilter权限过滤器
portorg.apache.shiro.web.filter.authz.PortFilter端口过滤器,可以设置是否是指定端口如果不是跳转到登录页面
restorg.apache.shiro.web.filter.authz.HttpMethodPermissionFilterhttp方法过滤器,可以指定如post不能进行访问等
rolesorg.apache.shiro.web.filter.authz.RolesAuthorizationFilter角色过滤器,判断当前用户是否指定角色
sslorg.apache.shiro.web.filter.authz.SslFilter请求需要通过ssl,如果不是跳转回登录页
userorg.apache.shiro.web.filter.authc.UserFilter如果访问一个已知用户,比如记住我功能,走这个过滤器

第五步:在spring-mvc.xml中配置权限的控制 异常的跳转

<!-- 保证 Shiro内部生命周期 -->
<bean class="org.apache.shiro.spring.LifecycleBeanPostProcessor"></bean>

<!-- 开启Shiro授权生效 -->
<bean 
class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor"/>

第六步:在controller中测试使用的验证登录

@RequestMapping(
			value="/subLogin", 
			method= RequestMethod.POST,
			produces="application/json;charset=utf-8")
	@ResponseBody
	public String subLogin(User user) {
		
		Subject subject = SecurityUtils.getSubject();
		
		UsernamePasswordToken token = new UsernamePasswordToken(user.getUsername(), user.getPassword());
		
		try {
			token.setRememberMe(user.isRememberMe());
			subject.login(token);
		} catch (Exception e) {
			return e.getMessage();
		}
		
		// 编码方式判断是否具有管理员身份
		if (subject.hasRole("admin")) {
			return "有admin权限";
		}
		
		return "无admin权限";
	}


会话管理SessionManager

这里主要是结合了redis进行Sesssion的管理,自定义了RedisSessionDao

<!-- 自定义SessionManager -->
   <bean class="com.shiro.session.CustomSessionManager" id="sessionManager">
       <property name="sessionDAO" ref="redisSessionDao"></property>
   </bean>

   <bean class="com.shiro.session.RedisSessionDao" id="redisSessionDao"></bean>

自定义CustomSessionManager

/**
 * @author Luke
 * @date 2018/6/11.
 */
public class CustomSessionManager extends DefaultWebSessionManager {

    @Override
    protected Session retrieveSession(SessionKey sessionKey) throws UnknownSessionException {
        Serializable sessionId = getSessionId(sessionKey);
        //获取request
        ServletRequest request = null;
        if (sessionKey instanceof WebSessionKey) {
            request = ((WebSessionKey) sessionKey).getServletRequest();
        }
        //若request不为空,并且sessionID不为空,则从request中获取session
        if (request != null && sessionId != null) {
            Session session = (Session) request.getAttribute(sessionId.toString());
            //获取到的session不为空,则返回
            if (session != null) {
                return session;
            }
        }

        //否则从redisSessionDao中获取session
        Session session = super.retrieveSession(sessionKey);
        //若获取的session不为空,则设值到request的作用域中
        if (request != null && sessionId != null) {
            request.setAttribute(sessionId.toString(), session);
        }

        return session;
    }
}
缓存管理CacheManager,也是结合Redis,从redis中获取缓存数据,提高性能
<bean class="com.shiro.cache.RedisCacheManager" id="cacheManager"></bean>

public class RedisCacheManager implements CacheManager {

    @Autowired
    private RedisCache redisCache;

    @Override
    public <K, V> Cache<K, V> getCache(String s) throws CacheException {
        return redisCache;
    }
}


只贴出部分源码,详细的请下载源码运行,内含sql脚本(resources/shiro.sql)

本文来自:Shiro整合SpringMVC之web搭建

更多博客请查看个人博客:https://blog.luke-lu.cn


评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值