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

服務(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

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 第一次处破女18分钟 | 国产香蕉97碰碰在线视频 | 久久er99热精品一区二区 | 无限资源在线观看高清 | 国产一区二区免费福利片 | 国产资源视频在线观看 | 色香婷婷| 日韩一级片在线免费观看 | 四虎影院永久网址 | 亚洲成色WWW久久网站夜月 | chaopeng在线视频进入 | 9久热这里只有精品视频在线观看 | 欧美日韩在线观看区一二 | 欧美成人免费草草影院视频 | 深夜精品高中女学生 | 德国高清freexxxx性 | 色综合视频在线观看 | 成人aqq| 久久永久视频 | 国产麻豆91欧美一区二区 | 日日网| 日本免费观看的视频在线 | 精品视频中文字幕 | 91插插插插 | 青草视频免费观看 | 成人免费播放 | www.色啪啪.com| 国产香蕉一区二区在线网站 | 免费看又黄又爽又猛的视频软件- | 1024亚洲精品国产 | 草莓香蕉绿巨人丝瓜榴莲18 | 免费视频专区一国产盗摄 | 国产成人一区二区三区影院免费 | 武侠古典久久亚洲精品 | 亚洲天堂三区 | 草莓绿巨人香蕉茄子芭乐 | 苍井空色欲迷墙 | 国内精品久久久久久中文字幕 | 按摩师他揉我奶好爽捏我奶 | 男人在线网址 | 免费看视频网站 |