一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務(wù)器之家:專注于服務(wù)器技術(shù)及軟件下載分享
分類導(dǎo)航

PHP教程|ASP.NET教程|JAVA教程|ASP教程|編程技術(shù)|正則表達(dá)式|

服務(wù)器之家 - 編程語言 - JAVA教程 - springmvc集成shiro登錄失敗處理操作

springmvc集成shiro登錄失敗處理操作

2020-09-26 21:26nosqlcoco JAVA教程

這篇文章主要介紹了springmvc集成shiro登錄失敗處理操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧

一般的登錄流程會(huì)有:用戶名不存在,密碼錯(cuò)誤,驗(yàn)證碼錯(cuò)誤等..

在集成shiro后,應(yīng)用程序的外部訪問權(quán)限以及訪問控制交給了shiro來管理。

shiro提供了兩個(gè)主要功能:認(rèn)證(Authentication)和授權(quán)(Authorization);認(rèn)證的作用是證明自身可以訪問,一般是用戶名加密碼,授權(quán)的作用是誰可以訪問哪些資源,通過開發(fā)者自己的用戶角色權(quán)限系統(tǒng)來控制。

shiro的會(huì)話管理和緩存管理不在本文范圍內(nèi)。

下面通過登錄失敗的處理流程來介紹springmvc與shiro的集成。

依賴項(xiàng)目

依賴名稱  版本
spring 4.1.4.RELEASE
shiro 1.2.2
self4j 1.7.5
log4j 1.2.17

在web.xml里配置shiro

?
1
2
3
4
5
6
7
8
9
10
11
12
<filter>
  <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>

新建一個(gè)spring-context-shiro.xml配置shiro相關(guān)信息,使用spring加載

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
<?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"
  xsi:schemaLocation="
    http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
    http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd"
  default-lazy-init="true">
 
  <description>Shiro Configuration</description>
  <!-- 安全認(rèn)證過濾器 -->
  <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
    <property name="securityManager" ref="securityManager" />
    <property name="loginUrl" value="/sys/login" />
    <property name="successUrl" value="/sys" />
    <property name="filters">
      <map>          <!--自定義登錄驗(yàn)證過濾器-->
        <entry key="authc" value-ref="formAuthenticationFilter" />
      </map>
    </property>
    <property name="filterChainDefinitions">
      <value>
        /sys/login = authc
        /sys/logout = logout
        /sys/** = user
      </value>
    </property>
  </bean>
 
  <!-- 定義 Shiro 主要業(yè)務(wù)對(duì)象 -->
  <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
    <property name="realm" ref="systemAuthorizingRealm" />
    <property name="cacheManager" ref="shiroCacheManager" />
  </bean>
  <!-- 會(huì)話ID生成器 -->
  <bean id="sessionIdGenerator" class="org.apache.shiro.session.mgt.eis.JavaUuidSessionIdGenerator"/>
  <!-- 會(huì)話管理器,設(shè)定會(huì)話超時(shí)及保存 -->
  <bean id="sessionManager" class="org.apache.shiro.web.session.mgt.DefaultWebSessionManager">
    <!-- 全局會(huì)話超時(shí)時(shí)間(單位毫秒),默認(rèn)30分鐘 -->
    <property name="globalSessionTimeout" value="1800000" />
    <property name="sessionDAO" ref="sessionDAO"/>
  </bean>
  <!-- 會(huì)話驗(yàn)證調(diào)度器,每30分鐘執(zhí)行一次驗(yàn)證 -->
  <!-- <bean id="sessionValidationScheduler" class="org.apache.shiro.session.mgt.quartz.QuartzSessionValidationScheduler"> -->
  <bean id="sessionValidationScheduler" class="org.apache.shiro.session.mgt.ExecutorServiceSessionValidationScheduler">
    <property name="interval" value="1800000"/>
    <property name="sessionManager" ref="sessionManager"/>
  </bean>
  <!-- sessionDAO保存認(rèn)證信息 -->
  <bean id="sessionDAO" class="org.apache.shiro.session.mgt.eis.EnterpriseCacheSessionDAO">
    <property name="activeSessionsCacheName" value="shiro-activeSessionCache" />
    <property name="cacheManager" ref="shiroCacheManager" />
    <property name="sessionIdGenerator" ref="sessionIdGenerator"/>
  </bean>
  <!-- 用戶授權(quán)信息Cache, 采用EhCache -->
  <bean id="shiroCacheManager" class="org.apache.shiro.cache.ehcache.EhCacheManager">
    <property name="cacheManager" ref="cacheManager" />
  </bean>
  <!-- Shiro生命周期處理器 -->
  <bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor" />
 
  <!-- AOP式方法級(jí)權(quán)限檢查 -->
  <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>

新建一個(gè)登錄認(rèn)證過濾器FormAuthenticationFilter.java

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.web.util.WebUtils;
import org.springframework.stereotype.Service;
 
/**
 * 表單驗(yàn)證(包含驗(yàn)證碼)過濾類*/
@Service
public class FormAuthenticationFilter extends org.apache.shiro.web.filter.authc.FormAuthenticationFilter {
  public static final String DEFAULT_CAPTCHA_PARAM = "validateCode";
 
  private String captchaParam = DEFAULT_CAPTCHA_PARAM;
 
  public String getCaptchaParam() {
    return captchaParam;
  }
 
  protected String getCaptcha(ServletRequest request) {
    return WebUtils.getCleanParam(request, getCaptchaParam());
  }
 
  protected AuthenticationToken createToken(ServletRequest request, ServletResponse response) {
    String username = getUsername(request);
    String password = getPassword(request);
    String locale = request.getParameter("locale");
    
    if (password == null) {
      password = "";
    }
    boolean rememberMe = isRememberMe(request);
    String host = getHost(request);
    String captcha = getCaptcha(request);
    return new UsernamePasswordToken(username, password.toCharArray(),locale, rememberMe, host, captcha);
  }
}

新建令牌類UsernamePasswordToken.java

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
package com.chunhui.webservice.modules.sys.security;
 
/**
 * 用戶和密碼(包含驗(yàn)證碼)令牌類*/
public class UsernamePasswordToken extends org.apache.shiro.authc.UsernamePasswordToken {
  private static final long serialVersionUID = 1L;
  private String captcha;
  private String locale;
  
  public String getCaptcha() {
    return captcha;
  }
 
  public void setCaptcha(String captcha) {
    this.captcha = captcha;
  }
 
  public String getLocale() {
    return locale;
  }
 
  public void setLocale(String locale) {
    this.locale = locale;
  }
 
  public UsernamePasswordToken() {
    super();
  }
 
  public UsernamePasswordToken(String username, char[] password, boolean rememberMe, String host, String captcha) {
    super(username, password, rememberMe, host);
    this.captcha = captcha;
  }
  public UsernamePasswordToken(String username, char[] password, String locale,boolean rememberMe, String host, String captcha) {
    super(username, password, rememberMe, host);
    this.captcha = captcha;
    this.locale = locale;
  }
}

最后一個(gè)是認(rèn)證實(shí)現(xiàn)類SystemAuthorizationRealm:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
package com.chunhui.webservice.modules.sys.security;
import java.io.Serializable;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.annotation.PostConstruct;
 
import com.chunhui.webservice.common.utils.EmployeeType;
import com.chunhui.webservice.common.utils.VertifyStatus;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.cache.Cache;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.subject.SimplePrincipalCollection;
import org.apache.shiro.subject.Subject;
import org.springframework.context.annotation.DependsOn;
import org.springframework.stereotype.Service;
import com.chunhui.webservice.common.servlet.ValidateCodeServlet;
import com.chunhui.webservice.common.utils.SpringContextHolder;
import com.chunhui.webservice.modules.sys.entity.Employee;
import com.chunhui.webservice.modules.sys.entity.Menu;
import com.chunhui.webservice.modules.sys.service.SystemService;
import com.chunhui.webservice.modules.sys.utils.SystemUtils;
import com.chunhui.webservice.modules.sys.web.LoginController;
 
/**
 * 系統(tǒng)安全認(rèn)證實(shí)現(xiàn)類*/
@Service
@DependsOn({ "employeeDao", "roleDao", "menuDao" })
public class SystemAuthorizingRealm extends AuthorizingRealm {
  private SystemService systemService;
 
  /**
   * 認(rèn)證回調(diào)函數(shù), 登錄時(shí)調(diào)用
   */
  @Override
  protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authcToken) throws AuthenticationException {
    UsernamePasswordToken token = (UsernamePasswordToken) authcToken;
// 判斷驗(yàn)證碼
    Session session = SecurityUtils.getSubject().getSession();
    // 設(shè)置獨(dú)立的session會(huì)話超時(shí)時(shí)間 session.setTimeout(60000);
    String code = (String) session.getAttribute(ValidateCodeServlet.VALIDATE_CODE);
    if (token.getCaptcha() == null || !token.getCaptcha().toUpperCase().equals(code)) {
      throw new CaptchaException("驗(yàn)證碼錯(cuò)誤!");
    }         //如果帳號(hào)不存在,輸出
    //throw new UnknownAccountException();
    
    //如果帳號(hào)被禁用,輸出     
    //throw new DisabledAccountException();
      
    //保存登錄時(shí)選擇的語言
    SecurityUtils.getSubject().getSession().setAttribute("locale", token.getLocale());
    try{
      SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(new Principal(employee), employee.getPassword(), getName());
      return info;
    }catch (Throwable t){
      t.printStackTrace();
      throw new AuthenticationException();
    }
  }/**
   * 授權(quán)查詢回調(diào)函數(shù), 進(jìn)行鑒權(quán)但緩存中無用戶的授權(quán)信息時(shí)調(diào)用
   */
  @Override
  protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
    Principal principal = (Principal) getAvailablePrincipal(principals);
    Employee employee = getSystemService().getEmployeeByName(principal.getUsername());
    if (employee != null) {
      SystemUtils.putCache("employee", employee);
      SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
      List<Menu> list = SystemUtils.getMenuList();
      for (Menu menu : list) {
        if (StringUtils.isNotBlank(menu.getPermission())) {
          // 添加基于Permission的權(quán)限信息
          for (String permission : StringUtils.split(menu.getPermission(), ",")) {
            info.addStringPermission(permission);
          }
        }
      }
      // 更新登錄IP和時(shí)間
      getSystemService().updateEmployeeLoginInfo(employee.getId());
      return info;
    } else {
      return null;
    }
  }
 
  /**
   * 清空用戶關(guān)聯(lián)權(quán)限認(rèn)證,待下次使用時(shí)重新加載
   */
  public void clearCachedAuthorizationInfo(String principal) {
    SimplePrincipalCollection principals = new SimplePrincipalCollection(principal, getName());
    clearCachedAuthorizationInfo(principals);
  }
 
  /**
   * 清空所有關(guān)聯(lián)認(rèn)證
   */
  public void clearAllCachedAuthorizationInfo() {
    Cache<Object, AuthorizationInfo> cache = getAuthorizationCache();
    if (cache != null) {
      for (Object key : cache.keys()) {
        cache.remove(key);
      }
    }
  }
 
  /**
   * 獲取系統(tǒng)業(yè)務(wù)對(duì)象
   */
  public SystemService getSystemService() {
    if (systemService == null) {
      systemService = SpringContextHolder.getBean(SystemService.class);
    }
    return systemService;
  }
 
  /**
   * 授權(quán)用戶信息
   */
  public static class Principal implements Serializable {
    private static final long serialVersionUID = 1L;
 
    private String id;
    private String username;
    private String realname;
    private Map<String, Object> cacheMap;
 
    public Principal(Employee employee) {
      this.id = employee.getId();
      this.username = employee.getUsername();
      this.realname = employee.getRealname();
    }
 
    public String getId() {
      return id;
    }
 
    public String getUsername() {
      return username;
    }
 
    public String getRealname() {
      return realname;
    }
 
    public Map<String, Object> getCacheMap() {
      if (cacheMap == null) {
        cacheMap = new HashMap<String, Object>();
      }
      return cacheMap;
    }
  }
}

那么在JSP頁面,可以通過獲取登錄異常具體的異常類型來在頁面顯示錯(cuò)誤原因

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<%String error = (String) request.getAttribute(FormAuthenticationFilter.DEFAULT_ERROR_KEY_ATTRIBUTE_NAME);%>
       <c:set var="exp_type" value="<%=error %>"/>
      <c:set var="tips" value=""></c:set>
      <c:if test="${fn:contains(exp_type,'CaptchaException')}">
        <c:set var="tips" value="驗(yàn)證碼錯(cuò)誤"></c:set>
      </c:if>
      <c:if test="${fn:contains(exp_type,'FailVertifyException')}">
        <c:set var="tips" value="該賬號(hào)審核未通過,不允許登陸!"></c:set>
      </c:if>
      <c:if test="${fn:contains(exp_type,'NotVertifyException')}">
        <c:set var="tips" value="該賬號(hào)正在審核中... 不允許登陸!"></c:set>
      </c:if>
      <c:if test="${fn:contains(exp_type,'UnknownAccountException')}">
        <c:set var="tips" value="賬號(hào)不存在!"></c:set>
      </c:if>
      <c:if test="${fn:contains(exp_type,'DisabledAccountException')}">
        <c:set var="tips" value="賬號(hào)不允許登陸!"></c:set>
      </c:if>
      <c:if test="${fn:contains(exp_type,'IncorrectCredentialsException')}">
        <c:set var="tips" value="密碼錯(cuò)誤!"></c:set>
      </c:if>

以上這篇springmvc集成shiro登錄失敗處理操作就是小編分享給大家的全部內(nèi)容了,希望能給大家一個(gè)參考,也希望大家多多支持服務(wù)器之家。

原文鏈接:https://www.cnblogs.com/nosqlcoco/p/5579081.html

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 欧美日韩免费一区二区在线观看 | 狠狠澡| 国产爽视频 | 国产日韩欧美色视频色在线观看 | 国产一区二区三区久久小说 | 亚洲精品久久久992KVTV | 亚洲国产天堂久久综合网站 | 成年人免费在线播放 | 男人午夜剧场 | 成人亚洲欧美日韩在线观看 | 91久久精品国产亚洲 | 亚洲AV无码专区国产精品麻豆 | 国产一久久香蕉国产线看观看 | 6080伦理久久精品亚洲 | 日韩伦理在线看 | 国产精品视频1区 | aaa一级特黄 | 色欧美亚洲 | 久久机热免费视频 | 日韩在线视频免费观看 | 亚洲黄色图 | 国产一级片视频 | 好大水好多好爽好硬好深视频 | 日韩免费观看成第15集 | 唯美清纯 自拍偷 | 亚洲欧美国产在线 | 16男男gaygays| 欧美一卡2卡3卡无卡 | 国产精品美女久久久久 | chinesemature老女人 | 美女脱得一二净无内裤全身的照片 | 男人狂躁女人下面狂叫图片 | 免费精品视频在线 | 999资源站 | 国产免费看视频 | 亚洲 欧美 成人 | 91九色国产porny | 国产精品高清一区二区三区不卡 | 向日葵视频app下载18岁以下勿看 | 日本高清在线精品一区二区三区 | videos护士有奶水 |