Shiro - 会话超时后重定向到登录页面 [英] Shiro - redirect to login page after session timeout

查看:106
本文介绍了Shiro - 会话超时后重定向到登录页面的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当会话超时时,我需要将我的 web 应用程序(Java + angular)重定向到登录页面.shiro 是自动进行重定向还是由代码处理?

I need to redirect my webapp (Java + angular) to login page when session is timed out. Does shiro do the redirection automatically or shall this be handled by code?

我尝试了几次黑客攻击,但对我不起作用.我尝试将会话超时添加到我的 web.xml 但它根本没有生效.我尝试更新我的 shiro.ini,但后来无法登录我的应用程序!

I tried several hacks but didn't work for me. I tried adding session timeout to my web.xml but it simply didn't take affect. I tried updating my shiro.ini, but then couldn't login to my app anymore!

能否请您帮忙找出这些文件中的问题或建议在这种情况下应该怎么做.

Can you please help to find what's wrong in these files or advice what sould be done in such a case.

提前致谢.

web.xml:

<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
  <display-name>ResourceManager</display-name>
  <welcome-file-list>
    <welcome-file>index.html</welcome-file>
    <welcome-file>index.htm</welcome-file>
    <welcome-file>index.jsp</welcome-file>
    <welcome-file>default.html</welcome-file>
    <welcome-file>default.htm</welcome-file>
    <welcome-file>default.jsp</welcome-file>
  </welcome-file-list>
  
  <!-- session-config>
    <session-timeout>1</session-timeout>
  </session-config>

  <error-page>
    <exception-type>javax.faces.application.ViewExpiredException</exception-type>
    <location>/Login.html</location>
  </error-page-->
  
  <listener>
    <listener-class>
    	com.<our customized package>.logging.AppLifeCircleListener
    	</listener-class>
  </listener>
  <listener>
    <listener-class>org.apache.shiro.web.env.EnvironmentLoaderListener</listener-class>
  </listener>
  <filter>
    <filter-name>shiro-filter</filter-name>
    <filter-class>org.apache.shiro.web.servlet.ShiroFilter</filter-class>
  </filter>
  <filter-mapping>
    <filter-name>shiro-filter</filter-name>
    <url-pattern>/*</url-pattern>
    <dispatcher>REQUEST</dispatcher>
    <dispatcher>FORWARD</dispatcher>
    <dispatcher>INCLUDE</dispatcher>
    <dispatcher>ERROR</dispatcher>
  </filter-mapping>
  <servlet>
    <servlet-name>login</servlet-name>
    <jsp-file>/Login.jsp</jsp-file>
  </servlet>
  <servlet>
    <servlet-name>rest</servlet-name>
    <servlet-class>
  			org.springframework.web.servlet.DispatcherServlet
 		</servlet-class>
    <init-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>/WEB-INF/rest-servlet.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
  </servlet>
  <servlet-mapping>
    <servlet-name>rest</servlet-name>
    <url-pattern>/management/*</url-pattern>
  </servlet-mapping>
  <servlet-mapping>
    <servlet-name>rest</servlet-name>
    <url-pattern>/privilege/*</url-pattern>
  </servlet-mapping>
  <servlet-mapping>
    <servlet-name>rest</servlet-name>
    <url-pattern>/file-explorer/*</url-pattern>
  </servlet-mapping>
  <servlet-mapping>
    <servlet-name>login</servlet-name>
    <url-pattern>/Login.html</url-pattern>
  </servlet-mapping>
</web-app>

shiro.ini :

shiro.ini :

[main]

# LDAP Settinng
contextFactory = com.ibm.datafabrication.web.server.security.JndiLdapContextFactoryExt
contextFactory.url = ldap://<host>:389
contextFactory.systemUsername = <...>
contextFactory.keyPath = <>
contextFactory.encodedSystemPassword = ...

ldapRealm = com.<>.ActiveDirectoryRealm
ldapRealm.ldapContextFactory = $contextFactory
ldapRealm.userSearchFilter = (sAMAccountName={0})
ldapRealm.groupNameAttribute = cn
ldapRealm.searchBase = DC=<...>,DC=<...>,DC=com
ldapRealm.groupRolesMap = dfp_users:user,dfp_admins:admin

# SQLite Setting
ds = org.sqlite.SQLiteDataSource
ds.url = jdbc:sqlite:<>.db
jdbcRealm = org.apache.shiro.realm.jdbc.JdbcRealm
jdbcRealm.dataSource = $ds
jdbcRealm.permissionsLookupEnabled = false
jdbcRealm.authenticationQuery = SELECT Password FROM Users WHERE Name=?
jdbcRealm.userRolesQuery = WITH uname(name) AS (VALUES(?)) SELECT 'user' FROM Users, uname WHERE Users.Name=uname.name UNION ALL SELECT 'admin' FROM (SELECT Id FROM Users, uname WHERE Users.Name=uname.name) LEFT JOIN Admins on Id = Admins.UserId WHERE UserId NOT NULL
credentialsMatcher = org.apache.shiro.authc.credential.Sha256CredentialsMatcher
credentialsMatcher.storedCredentialsHexEncoded = true
jdbcRealm.credentialsMatcher = $credentialsMatcher

authc.loginUrl = /Login.html
securityManager.realms = $jdbcRealm

authcStrategy = org.apache.shiro.authc.pam.FirstSuccessfulStrategy
securityManager.authenticator.authenticationStrategy = $authcStrategy

>>>>>>>>>>>>>>>>>>>>> What I tired

# session timeout
sessionManager = org.apache.shiro.web.session.mgt.DefaultWebSessionManager
securityManager.sessionMode=native
securityManager.sessionManager.globalSessionTimeout = 60000
securityManager.sessionManager = $sessionManager

sessionValidationScheduler = org.apache.shiro.session.mgt.ExecutorServiceSessionValidationScheduler
sessionValidationScheduler.interval = 30000
securityManager.sessionManager.sessionValidationScheduler = $sessionValidationScheduler

<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

[urls]
/logout = logout
/css/** = anon
/images/** = anon
/plugins/** = anon
/favicon.ico = anon
/tdf.ico = anon
/Login.html = authc
...
/** = authc, roles[user]

推荐答案

您可以保留 web.xml 原样,因为 Shiro 与此文件中的配置无关.servlet 的 HttpServletRequest 和 Shiro Session 使用的 HttpSession 有所不同.它们是完全不同的东西.所以不要对 servlet 的会话配置和 Shiro 的会话配置感到困惑.在这种情况下,我们让 Shiro 处理您的会话.

You can leave your web.xml as it is since Shiro has nothing to do with the configruation in this file. There is a difference in the HttpSession used by the HttpServletRequest of your servlet and the Shiro Session. They are completely different things. So don't get confused by the session configuration by the servlet and the one by Shiro. We let Shiro handle your session in this case.

您的 shiro.ini 有问题
您正在覆盖您正在写入 DefaultWebSessionManager 的设置:

sessionManager = org.apache.shiro.web.session.mgt.DefaultWebSessionManager // Define a sessionManager variable
securityManager.sessionMode=native
securityManager.sessionManager.globalSessionTimeout = 60000 // set a securityManager.sessionManager property
securityManager.sessionManager = $sessionManager // override the property by setting the object

你必须先设置对象:

sessionManager = org.apache.shiro.web.session.mgt.DefaultWebSessionManager
securityManager.sessionManager = $sessionManager
securityManager.sessionMode=native
securityManager.sessionManager.globalSessionTimeout = 60000

您不需要 ExecutorServiceSessionValidationScheduler,因为 DefaultWebSessionManager 已经提供了验证器.一个工作示例可能如下所示:

You don't need the ExecutorServiceSessionValidationScheduler since a valdiator is provided by the DefaultWebSessionManager already. A working example could look like the following:

sessionManager = org.apache.shiro.web.session.mgt.DefaultWebSessionManager
# Session timeout token_ttl_ms = 14 days
sessionManager.globalSessionTimeout = 1209600000
# Session valdiation = 15 minutes
sessionManager.sessionValidationInterval = 900000

securityManager = org.apache.shiro.web.mgt.DefaultWebSecurityManager
securityManager.sessionManager = $sessionManager

DefaultWebSessionManager

DefaultWebSessionManager 提供了您正在寻找的所有开箱即用的功能(基本上).当会话过期时,DefaultWebSessionManager 在其 super 通知所有听众关于 SessionManager.您只需注册一个 SessionListener 到您的 SessionManager 并在其 onExpiration 方法触发重新加载或重定向.也许这种方式比较适合jsp/jspx应用.
无论如何,在官方文档中阅读如何注册会话侦听器此处.

The DefaultWebSessionManager provides all the functionality you are looking for out of the box (basically). When a session expires the DefaultWebSessionManager calls onExpiration on its super which notifys all its listeners about the expiration in the SessionManager. You simply could register a SessionListener to your SessionManager and trigger a reload or redirect at its onExpiration method. Maybe this approach is rather suitable for jsp/jspx applications.
Anyway, read how to register a session listener here in the official docs.

替代方法

另一种方法可能是让您的客户端管理会话状态,并通过调用您的服务让它持续检查是否过期.这可以通过计时器或 JavaScript 中的循环来完成.

A different approach could be to have your client manage the session state and let it continuously check for expiration by calling your service. This could be done by a timer or in a loop in JavaScript.

注意

org.apache.shiro.authc.credential.Sha256CredentialsMatcher 自 2010 年起已弃用.
使用 HashedCredentialsMatcher 直接设置它的 hashAlgorithmName 属性.

org.apache.shiro.authc.credential.Sha256CredentialsMatcher is deprecated since 2010.
Use the HashedCredentialsMatcher directly and set its hashAlgorithmName property.

这篇关于Shiro - 会话超时后重定向到登录页面的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆