原创

SpringMVC集成Shiro权限实现登录控制简单封装案例

Apache Shiro是一个强大且易用的Java安全框架,执行身份验证、授权、密码学和会话管理。使用Shiro的易于理解的API,您可以快速、轻松地获得任何应用程序,从最小的移动应用程序到最大的网络和企业应用程序。下面主要讲述一下SpringMVC集成Shiro权限实现登录控制简单封装案例。


1.springmvc整合shiro权限,首先需要引入相关的jar包,maven项目中pom.xml文件,新增jar配置依赖,内容如下:

<!--shiro相关包-->
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-core</artifactId>
<version>1.2.4</version>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-web</artifactId>
<version>1.2.4</version>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-quartz</artifactId>
<version>1.2.4</version>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>1.2.4</version>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-aspectj</artifactId>
<version>1.2.4</version>
</dependency>


2.新建AuthenticationFilter.java类文件,具体内容如下:

package com.yoodb.core.shiro.filter;
import java.io.IOException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.web.filter.PathMatchingFilter;
import org.apache.shiro.web.util.WebUtils;
public class AuthenticationFilter extends PathMatchingFilter{
private String failureUrl;
private String successUrl;
 @Override
 protected boolean onPreHandle(ServletRequest request, ServletResponse response, Object mappedValue) throws Exception {
        if (SecurityUtils.getSubject().isAuthenticated()) {
            return true;
        }
        HttpServletRequest req = (HttpServletRequest) request;
        HttpServletResponse resp = (HttpServletResponse) response;
        if (isLoginRequest(req)) {
            if ("post".equalsIgnoreCase(req.getMethod())) {
                boolean loginSuccess = login(req);
                if (loginSuccess) {
                redirectToSuccessUrl(req, resp);
                }
            }else {
            saveRequestAndRedirectToLogin(req, resp);
            }
        }
        return true;
    }
 private boolean redirectToSuccessUrl(HttpServletRequest req, HttpServletResponse resp) throws IOException {
        WebUtils.redirectToSavedRequest(req, resp, successUrl);
        return false;
    }
    private void saveRequestAndRedirectToLogin(HttpServletRequest req, HttpServletResponse resp) throws IOException {
        WebUtils.saveRequest(req);
        WebUtils.issueRedirect(req, resp, failureUrl);
    }
    private boolean login(HttpServletRequest req) {
        String username = req.getParameter("username");
        String password = req.getParameter("password");
        try {
            SecurityUtils.getSubject().login(new UsernamePasswordToken(username, password));
        } catch (Exception e) {
            req.setAttribute("shiroLoginFailure", e.getClass());
            return false;
        }
        return true;
    }
    private boolean isLoginRequest(HttpServletRequest req) {
        return pathsMatch(successUrl, WebUtils.getPathWithinApplication(req));
    }
public String getFailureUrl() {
return failureUrl;
}
public void setFailureUrl(String failureUrl) {
this.failureUrl = failureUrl;
}
public String getSuccessUrl() {
return successUrl;
}
public void setSuccessUrl(String successUrl) {
this.successUrl = successUrl;
}
}


3.Realm充当Shiro与应用安全数据间的“桥梁”或者“连接器”。也就是说,当对用户执行认证(登录)和授权(访问控制)验证时,Shiro会从应用配置的Realm中查找用户及其权限信息。添加Realm类,新建UserRealm.java类文件,具体内容如下:

package com.yoodb.core.shiro.realm;
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.UnknownAccountException;
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.subject.PrincipalCollection;
public class UserRealm extends AuthorizingRealm {
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
        authorizationInfo.setRoles(null);
        authorizationInfo.setStringPermissions(null);
        return authorizationInfo;
    }
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
// TODO Auto-generated method stub
UsernamePasswordToken upToken = (UsernamePasswordToken)token;
//获得用户名与密码  
    String username = upToken.getUsername();  
//    if(!"wang".equals(username)) {  
//            throw new UnknownAccountException(); //如果用户名错误  
//        }
    String password = String.valueOf(upToken.getPassword());
    SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(username, password .toCharArray(),getName());  
    return info;  
}
}


4.Shiro的核心部分是SecurityManager,它负责安全认证与授权。Shiro本身已经实现了所有的细节,用户可以完全把它当做一个黑盒来使用。SecurityUtils对象,本质上就是一个工厂类似Spring中的ApplicationContext。Subject是初学者比较难于理解的对象,很多人以为它可以等同于User,其实不然。Subject中文翻译:项目,而正确的理解也恰恰如此。它是你目前所设计的需要通过Shiro保护的项目的一个抽象概念。通过令牌(token)与项目(subject)的登陆(login)关系,Shiro保证了项目整体的安全。

新建spring-shiro.xml文件,具体内容如下:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:util="http://www.springframework.org/schema/util"
       xmlns:aop="http://www.springframework.org/schema/aop"
       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
       http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd
       http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
    <!-- Realm实现 -->
    <bean id="userRealm" class="com.yoodb.core.shiro.realm.UserRealm"/>
    <!-- 安全管理器 -->
    <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
        <property name="realm" ref="userRealm"/>
    </bean>
<bean id="authenticatorFilter" class="com.yoodb.core.shiro.filter.AuthenticationFilter">
<!-- 配置验证错误时的失败页面 -->
<property name="failureUrl" value="/login" />
<property name="successUrl" value="/index" />
</bean>
    <!-- Shiro的Web过滤器 -->
    <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
        <property name="securityManager" ref="securityManager"/>
<property name="filters">
            <util:map>
                <entry key="authc" value-ref="authenticatorFilter"/>
            </util:map>
        </property>
        <property name="loginUrl" value="/login" />
        <property name="filterChainDefinitions">
            <value>
                /login = authc
                /logout = logout
            </value>
        </property>
    </bean>
</beans>


5.在spring相关的配置文件中,增加配置信息如下:

<import resource="classpath:conf/spring-shiro.xml"/>


6.修改web.xml文件增加Shiro Filter过滤器配置,具体内容如下:

<!-- Shiro 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>/*</url-pattern>   
<dispatcher>REQUEST</dispatcher> 
</filter-mapping>

关注下方微信公众号“Java精选”(w_z90110),回复关键字领取资料:如HadoopDubboCAS源码等等,免费领取资料视频和项目。 

涵盖:程序人生、搞笑视频、算法与数据结构、黑客技术与网络安全、前端开发、Java、Python、Redis缓存、Spring源码、各大主流框架、Web开发、大数据技术、Storm、Hadoop、MapReduce、Spark、elasticsearch、单点登录统一认证、分布式框架、集群、安卓开发、iOS开发、C/C++、.NET、Linux、Mysql、Oracle、NoSQL非关系型数据库、运维等。

评论

  1. #1

    (2018/01/16 16:57:10)回复
    一辈子只做好一件事!我是有多么的大方吖!哈哈

分享:

支付宝

微信